summaryrefslogtreecommitdiff
path: root/xc
diff options
context:
space:
mode:
authorbrianp <brianp>2000-06-07 16:06:39 +0000
committerbrianp <brianp>2000-06-07 16:06:39 +0000
commitd374f65d7bc9591d7a431b682ef20f4001120eee (patch)
tree9f59163fb0eb27d2d68a8c454e2acaaf4c4e3b64 /xc
parent24bd6ba6296ab8c6e812875e9fcd0ed24eecf9d3 (diff)
merge from trunkglxmisc-3-0-0-20000607
Diffstat (limited to 'xc')
-rw-r--r--xc/config/cf/FreeBSD.cf4
-rw-r--r--xc/config/cf/host.def13
-rw-r--r--xc/config/cf/xfree86.cf13
-rw-r--r--xc/include/GL/glx.h113
-rw-r--r--xc/include/GL/glxtokens.h189
-rw-r--r--xc/lib/GL/Imakefile16
-rw-r--r--xc/lib/GL/dri/XF86dri.c2
-rw-r--r--xc/lib/GL/dri/drm/Imakefile14
-rw-r--r--xc/lib/GL/mesa/src/Imakefile4
-rw-r--r--xc/lib/GL/mesa/src/X86/Imakefile13
-rw-r--r--xc/lib/GL/mesa/src/drv/Imakefile13
-rw-r--r--xc/lib/GL/mesa/src/drv/common/Imakefile10
-rw-r--r--xc/lib/GL/mesa/src/drv/gamma/Imakefile236
-rw-r--r--xc/lib/GL/mesa/src/drv/gamma/gamma_gl.c1113
-rw-r--r--xc/lib/GL/mesa/src/drv/gamma/gamma_init.h11
-rw-r--r--xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c109
-rw-r--r--xc/lib/GL/mesa/src/drv/gamma/gamma_matrix.c2
-rw-r--r--xc/lib/GL/mesa/src/drv/gamma/gamma_regs.h35
-rw-r--r--xc/lib/GL/mesa/src/drv/gamma/gamma_texture.c5
-rw-r--r--xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c43
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/Imakefile263
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h89
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c108
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810clear.c193
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810clear.h7
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810context.h55
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dd.c2
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810dma.h186
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810ioctl.c477
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810ioctl.h36
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810lib.h130
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810pipeline.c6
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810span.c4
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810state.c569
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810state.h3
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810swap.c259
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810swap.h6
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tex.c196
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tex.h5
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tris.c1
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tris.h93
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810tritmp.h81
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810vb.c2
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/Imakefile275
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c44
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h71
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaeltpath.c457
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaelttmp.h269
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgafastpath.c10
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h60
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaioctl.c673
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgaioctl.h35
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgalib.h32
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgapipeline.h3
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgarender.c334
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgarender.h10
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgastate.c364
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatex.c492
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatris.c58
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgatritmp.h40
-rw-r--r--xc/lib/GL/mesa/src/drv/mga/mgavb.c2
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/Imakefile325
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_cce.c389
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_cce.h142
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_ccevb.h224
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_clear.c248
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_clear.h47
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_context.c203
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_context.h219
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_dd.c182
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_dd.h44
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c551
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_fastpath.h48
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h155
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_init.h92
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_lock.h134
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_mesa.h43
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c126
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h43
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_screen.c258
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_screen.h129
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_span.c329
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_span.h44
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_state.c1309
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_state.h50
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_swap.c125
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_swap.h43
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tex.c1851
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tex.h82
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_texobj.h87
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tris.c548
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tris.h76
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h327
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_vb.c470
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_vb.h150
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c257
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_xmesa.h44
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/Imakefile25
-rw-r--r--xc/programs/Xserver/GL/dri/dri.c8
-rw-r--r--xc/programs/Xserver/Imakefile2
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml377
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/DRIcomp.sgml501
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile6
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_accel.c38
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_dac.c3
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h4
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dga.c294
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c74
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h2
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h8
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c3
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h66
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile9
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h3
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c16
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c83
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c25
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i810/i810_memory.c8
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c46
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h125
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/Imakefile21
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h113
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c102
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_cursor.c111
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c1242
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.h116
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dripriv.h54
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c447
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h601
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_sarea.h77
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/xf86sym.c10
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/Imakefile3
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/Imakefile18
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/Imakefile41
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/drmmodule.c56
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/Imakefile31
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/Makefile.bsd5
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm.h359
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/Makefile17
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/agpsupport.c271
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/auth.c168
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/bufs.c500
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/context.c297
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/dma.c534
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/drawable.c50
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/drmstat.c418
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/fops.c260
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/init.c101
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/ioctl.c120
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/lists.c258
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/lock.c220
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/memory.c458
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/proc.c568
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/sysctl.c554
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/vm.c104
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h708
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma/Makefile15
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma/gamma_dma.c802
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma/gamma_drv.c574
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma/gamma_drv.h50
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/i810_drm.h188
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/mga_drm.h269
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/r128_drm.h111
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/tdfx/Makefile15
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/tdfx/tdfx_context.c201
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/tdfx/tdfx_drv.c694
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/tdfx/tdfx_drv.h47
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drm.c1108
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmHash.c435
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmI810.c86
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmMga.c116
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmR128.c198
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmRandom.c219
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmSL.c490
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile15
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel20
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux9
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/agpsupport.c2
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h24
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h11
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c30
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c39
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h2
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c111
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c717
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h188
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c8
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h66
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c413
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h54
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c1
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h142
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c634
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c2
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_bufs.c309
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_context.c214
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_dma.c908
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h111
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c737
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h226
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c28
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c87
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c199
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h24
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h42
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h46
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h147
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h80
208 files changed, 35610 insertions, 3745 deletions
diff --git a/xc/config/cf/FreeBSD.cf b/xc/config/cf/FreeBSD.cf
index 1043ed8bf..c92902d37 100644
--- a/xc/config/cf/FreeBSD.cf
+++ b/xc/config/cf/FreeBSD.cf
@@ -82,7 +82,7 @@ XCOMM operating system: OSName (OSMajorVersion./**/OSMinorVersion./**/OSTeenyVe
#if defined(UseInstalled)
#define DefaultCCOptions /**/
#else
-#define DefaultCCOptions -ansi -pedantic -Dasm=__asm GccWarningOptions
+/*#define DefaultCCOptions -ansi -pedantic -Dasm=__asm GccWarningOptions*/
#endif
#ifndef ExtraLibraries
/* support for multi-byte locales is in libxpg4 rather than libc */
@@ -464,7 +464,7 @@ install.man:: @@\
* A hack to work around an optimisation problem with the compiler on
* FreeBSD 4.0-current in late 1999/early 2000.
*/
-#if OSMajorVersion == 4 && OSMinorVersion == 0 && OSTeenyVersion == 0
+#if (OSMajorVersion == 4 || OSMajorVersion == 5) && OSMinorVersion == 0 && OSTeenyVersion == 0
#define FreeBSDGccOptBug
#endif
diff --git a/xc/config/cf/host.def b/xc/config/cf/host.def
index 8b3406a77..8b164f632 100644
--- a/xc/config/cf/host.def
+++ b/xc/config/cf/host.def
@@ -1,8 +1,8 @@
-#define ProjectRoot /usr/XF86-glxmisc
+
#define DefaultGcc2i386Opt -O2
#define LibraryCDebugFlags -O2
#define BuildServersOnly YES
-#define XF86CardDrivers vga tdfx i810 mga glint r128
+#define XF86CardDrivers vga tdfx i810 mga r128
#define LinuxDistribution LinuxRedHat
#define GccWarningOptions -Wall -Wpointer-arith -Wstrict-prototypes \
-Wmissing-prototypes -Wmissing-declarations \
@@ -17,9 +17,16 @@
/* #define GlxBuiltInTdfx YES */
/* #define GlxBuiltInI810 YES */
/* #define GlxBuiltInMga YES */
+/* #define GlxBuiltInR128 YES */
/* #define DoLoadableServer NO */
-#define SharedLibFont NO
+/* Optionally turn this on to change the place where you install the build */
+/* #define ProjectRoot /usr/XF86-main */
+
+/* Optionally turn this on to force the kernel modules to build */
+/* #define BuildXF86DRM YES */
+
+#define SharedLibFont NO
#define XnestServer NO
#define XVirtualFramebufferServer NO
#define XprtServer NO
diff --git a/xc/config/cf/xfree86.cf b/xc/config/cf/xfree86.cf
index 77e5e454d..5f5991c77 100644
--- a/xc/config/cf/xfree86.cf
+++ b/xc/config/cf/xfree86.cf
@@ -512,12 +512,21 @@ IPLAN2P8_DEFS = -DUSE_IPLAN2P8
# ifndef GlxBuiltInTdfx
# define GlxBuiltInTdfx NO
# endif
+# ifndef GlxBuiltInMga
+# define GlxBuiltInMga NO
+# endif
+# ifndef GlxBuiltInI810
+# define GlxBuiltInI810 NO
+# endif
+# ifndef GlxBuiltInR128
+# define GlxBuiltInR128 NO
+# endif
-# if GlxBuiltInTdfx
+# if GlxBuiltInTdfx || GlxBuiltInMga || GlxBuiltInI810 || GlxBuiltInR128
# define GlxDriverUsesMesa YES
# endif
-# if GlxBuiltInGamma || GlxBuiltInMesa || GlxBuiltInTdfx
+# if GlxBuiltInGamma || GlxBuiltInTdfx || GlxBuiltInMga || GlxBuiltInI810 || GlxBuiltInR128 || GlxBuiltInMesa
# define GlxUseBuiltInDRIDriver YES
# define DRIDynLoadDefines /**/
# else
diff --git a/xc/include/GL/glx.h b/xc/include/GL/glx.h
index 367ce0a51..e4712b95f 100644
--- a/xc/include/GL/glx.h
+++ b/xc/include/GL/glx.h
@@ -1,26 +1,38 @@
#ifndef __GLX_glx_h__
#define __GLX_glx_h__
-/* $XFree86: xc/include/GL/glx.h,v 1.5 2000/03/02 16:07:29 martin Exp $ */
/*
-** The contents of this file are subject to the GLX Public License Version 1.0
-** (the "License"). You may not use this file except in compliance with the
-** License. You may obtain a copy of the License at Silicon Graphics, Inc.,
-** attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
-** or at http://www.sgi.com/software/opensource/glx/license.html.
-**
-** Software distributed under the License is distributed on an "AS IS"
-** basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY
-** IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
-** PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific
-** language governing rights and limitations under the License.
-**
-** The Original Software is GLX version 1.2 source code, released February,
-** 1999. The developer of the Original Software is Silicon Graphics, Inc.
-** Those portions of the Subject Software created by Silicon Graphics, Inc.
-** are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.
-**
-** $SGI$
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
*/
#include <X11/Xlib.h>
@@ -39,19 +51,19 @@ extern "C" {
typedef XID GLXContextID;
typedef XID GLXPixmap;
typedef XID GLXDrawable;
-/* GLX 1.3 */
-typedef XID GLXFBConfigID;
-typedef XID GLXPfuffer;
-typedef XID GLXWindow;
typedef XID GLXPbuffer;
-typedef XID GLXFBConfig;
-
+typedef XID GLXWindow;
+typedef XID GLXFBConfigID;
/*
** GLXContext is a pointer to opaque data.
-**/
+*/
typedef struct __GLXcontextRec *GLXContext;
+/*
+** GLXFBConfig is a pointer to opaque data.
+*/
+typedef struct __GLXFBConfigRec *GLXFBConfig;
/************************************************************************/
@@ -76,34 +88,57 @@ extern const char * glXGetClientString (Display *dpy, int name );
extern const char * glXQueryServerString (Display *dpy, int screen, int name );
extern const char * glXQueryExtensionsString (Display *dpy, int screen );
-/* GLX 1.3 */
-extern GLXFBConfig glXChooseFBConfig (Display *dpy, int screen, const int *attribList, int *nitems);
+/* New for GLX 1.3 */
+extern GLXFBConfig * glXGetFBConfigs (Display *dpy, int screen, int *nelements);
+extern GLXFBConfig * glXChooseFBConfig (Display *dpy, int screen, const int *attrib_list, int *nelements);
extern int glXGetFBConfigAttrib (Display *dpy, GLXFBConfig config, int attribute, int *value);
extern XVisualInfo * glXGetVisualFromFBConfig (Display *dpy, GLXFBConfig config);
-extern GLXWindow glXCreateWindow (Display *dpy, GLXFBConfig config, Window win, const int *attribList);
-extern void glXDestroyWindow (Display *dpy, GLXWindow window);
-extern GLXPixmap glXCreatePixmap (Display *dpy, GLXFBConfig config,Pixmap pixmap, const int *attribList);
+extern GLXWindow glXCreateWindow (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list);
+extern void glXDestroyWindow (Display *dpy, GLXWindow win);
+extern GLXPixmap glXCreatePixmap (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list);
extern void glXDestroyPixmap (Display *dpy, GLXPixmap pixmap);
-extern GLXPbuffer glXCreatePbuffer (Display *dpy, GLXFBConfig config, const int *attribList);
+extern GLXPbuffer glXCreatePbuffer (Display *dpy, GLXFBConfig config, const int *attrib_list);
extern void glXDestroyPbuffer (Display *dpy, GLXPbuffer pbuf);
extern void glXQueryDrawable (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
-extern GLXContext glXCreateNewContext (Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct);
-extern Bool glXMakeContextCurrent (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+extern GLXContext glXCreateNewContext (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+extern Bool glXMakeContextCurrent (Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
extern GLXDrawable glXGetCurrentReadDrawable (void);
+extern Display * glXGetCurrentDisplay (void);
extern int glXQueryContext (Display *dpy, GLXContext ctx, int attribute, int *value);
-extern void glXSelectEvent (Display *dpy, GLXDrawable drawable, unsigned long mask);
-extern void glXGetSelectedEvent (Display *dpy, GLXDrawable drawable, unsigned long *mask);
+extern void glXSelectEvent (Display *dpy, GLXDrawable draw, unsigned long event_mask);
+extern void glXGetSelectedEvent (Display *dpy, GLXDrawable draw, unsigned long *event_mask);
-/* Extensions */
-extern Display * glXGetCurrentDisplay (void);
+/*** SGI GLX extensions */
extern GLXContextID glXGetContextIDEXT (const GLXContext ctx);
extern GLXDrawable glXGetCurrentDrawableEXT (void);
extern GLXContext glXImportContextEXT (Display *dpy, GLXContextID contextID);
extern void glXFreeContextEXT (Display *dpy, GLXContext ctx);
extern int glXQueryContextInfoEXT (Display *dpy, GLXContext ctx, int attribute, int *value);
-extern void (*glXGetProcAddressARB(const GLubyte *procName))();
+extern void (*glXGetProcAddressARB(const GLubyte *procName))( void );
+
+/*** Should these go here, or in another header? */
+/*
+** GLX Events
+*/
+typedef struct {
+ int event_type; /* GLX_DAMAGED or GLX_SAVED */
+ int draw_type; /* GLX_WINDOW or GLX_PBUFFER */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came for SendEvent request */
+ Display *display; /* display the event was read from */
+ GLXDrawable drawable; /* XID of Drawable */
+ unsigned int buffer_mask; /* mask indicating which buffers are affected */
+ unsigned int aux_buffer; /* which aux buffer was affected */
+ int x, y;
+ int width, height;
+ int count; /* if nonzero, at least this many more */
+} GLXPbufferClobberEvent;
+typedef union __GLXEvent {
+ GLXPbufferClobberEvent glxpbufferclobber;
+ long pad[24];
+} GLXEvent;
#ifdef __cplusplus
}
diff --git a/xc/include/GL/glxtokens.h b/xc/include/GL/glxtokens.h
index 5a3e219c3..4efa20a71 100644
--- a/xc/include/GL/glxtokens.h
+++ b/xc/include/GL/glxtokens.h
@@ -1,26 +1,38 @@
#ifndef __GLX_glxtokens_h__
#define __GLX_glxtokens_h__
-/* $XFree86: xc/include/GL/glxtokens.h,v 1.3 2000/02/15 07:13:24 martin Exp $ */
/*
-** The contents of this file are subject to the GLX Public License Version 1.0
-** (the "License"). You may not use this file except in compliance with the
-** License. You may obtain a copy of the License at Silicon Graphics, Inc.,
-** attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
-** or at http://www.sgi.com/software/opensource/glx/license.html.
-**
-** Software distributed under the License is distributed on an "AS IS"
-** basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY
-** IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
-** PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific
-** language governing rights and limitations under the License.
-**
-** The Original Software is GLX version 1.2 source code, released February,
-** 1999. The developer of the Original Software is Silicon Graphics, Inc.
-** Those portions of the Subject Software created by Silicon Graphics, Inc.
-** are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.
-**
-** $SGI$
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
*/
#ifdef __cplusplus
@@ -29,9 +41,10 @@ extern "C" {
#define GLX_VERSION_1_1 1
#define GLX_VERSION_1_2 1
+#define GLX_VERSION_1_3 1
/*
-** Names for attributes to glXGetConfig.
+** Visual Config Attributes (glXGetConfig, glXGetFBConfigAttrib)
*/
#define GLX_USE_GL 1 /* support GLX rendering */
#define GLX_BUFFER_SIZE 2 /* depth of the color buffer */
@@ -39,7 +52,7 @@ extern "C" {
#define GLX_RGBA 4 /* true if RGBA mode */
#define GLX_DOUBLEBUFFER 5 /* double buffering supported */
#define GLX_STEREO 6 /* stereo buffering supported */
-#define GLX_AUX_BUFFERS 7 /* number of aux buffers */
+#define GLX_AUX_BUFFERS 7 /* number of aux buffers */
#define GLX_RED_SIZE 8 /* number of red component bits */
#define GLX_GREEN_SIZE 9 /* number of green component bits */
#define GLX_BLUE_SIZE 10 /* number of blue component bits */
@@ -50,6 +63,25 @@ extern "C" {
#define GLX_ACCUM_GREEN_SIZE 15 /* number of green accum bits */
#define GLX_ACCUM_BLUE_SIZE 16 /* number of blue accum bits */
#define GLX_ACCUM_ALPHA_SIZE 17 /* number of alpha accum bits */
+/*
+** FBConfig-specific attributes
+*/
+#define GLX_X_VISUAL_TYPE 0x22
+#define GLX_CONFIG_CAVEAT 0x20 /* Like visual_info VISUAL_CAVEAT_EXT */
+#define GLX_TRANSPARENT_TYPE 0x23
+#define GLX_TRANSPARENT_INDEX_VALUE 0x24
+#define GLX_TRANSPARENT_RED_VALUE 0x25
+#define GLX_TRANSPARENT_GREEN_VALUE 0x26
+#define GLX_TRANSPARENT_BLUE_VALUE 0x27
+#define GLX_TRANSPARENT_ALPHA_VALUE 0x28
+#define GLX_DRAWABLE_TYPE 0x8010
+#define GLX_RENDER_TYPE 0x8011
+#define GLX_X_RENDERABLE 0x8012
+#define GLX_FBCONFIG_ID 0x8013
+#define GLX_MAX_PBUFFER_WIDTH 0x8016
+#define GLX_MAX_PBUFFER_HEIGHT 0x8017
+#define GLX_MAX_PBUFFER_PIXELS 0x8018
+#define GLX_VISUAL_ID 0x800B
/*
** Error return values from glXGetConfig. Success is indicated by
@@ -59,9 +91,85 @@ extern "C" {
#define GLX_BAD_ATTRIBUTE 2 /* attribute to get is bad */
#define GLX_NO_EXTENSION 3 /* no glx extension on server */
#define GLX_BAD_VISUAL 4 /* visual # not known by GLX */
-#define GLX_BAD_CONTEXT 5
-#define GLX_BAD_VALUE 6
-#define GLX_BAD_ENUM 7
+#define GLX_BAD_CONTEXT 5 /* returned only by import_context EXT? */
+#define GLX_BAD_VALUE 6 /* returned only by glXSwapIntervalSGI? */
+#define GLX_BAD_ENUM 7 /* unused? */
+
+/* FBConfig attribute values */
+
+/*
+** Generic "don't care" value for glX ChooseFBConfig attributes (except
+** GLX_LEVEL)
+*/
+#define GLX_DONT_CARE 0xFFFFFFFF
+
+/* GLX_RENDER_TYPE bits */
+#define GLX_RGBA_BIT 0x00000001
+#define GLX_COLOR_INDEX_BIT 0x00000002
+
+/* GLX_DRAWABLE_TYPE bits */
+#define GLX_WINDOW_BIT 0x00000001
+#define GLX_PIXMAP_BIT 0x00000002
+#define GLX_PBUFFER_BIT 0x00000004
+
+/* GLX_CONFIG_CAVEAT attribute values */
+#define GLX_NONE 0x8000
+#define GLX_SLOW_CONFIG 0x8001
+#define GLX_NON_CONFORMANT_CONFIG 0x800D
+
+/* GLX_X_VISUAL_TYPE attribute values */
+#define GLX_TRUE_COLOR 0x8002
+#define GLX_DIRECT_COLOR 0x8003
+#define GLX_PSEUDO_COLOR 0x8004
+#define GLX_STATIC_COLOR 0x8005
+#define GLX_GRAY_SCALE 0x8006
+#define GLX_STATIC_GRAY 0x8007
+
+/* GLX_TRANSPARENT_TYPE attribute values */
+/* #define GLX_NONE 0x8000 */
+#define GLX_TRANSPARENT_RGB 0x8008
+#define GLX_TRANSPARENT_INDEX 0x8009
+
+/* glXCreateGLXPbuffer attributes */
+#define GLX_PRESERVED_CONTENTS 0x801B
+#define GLX_LARGEST_PBUFFER 0x801C
+#define GLX_PBUFFER_HEIGHT 0x8040 /* New for GLX 1.3 */
+#define GLX_PBUFFER_WIDTH 0x8041 /* New for GLX 1.3 */
+
+/* glXQueryGLXPBuffer attributes */
+#define GLX_WIDTH 0x801D
+#define GLX_HEIGHT 0x801E
+#define GLX_EVENT_MASK 0x801F
+
+/* glXCreateNewContext render_type attribute values */
+#define GLX_RGBA_TYPE 0x8014
+#define GLX_COLOR_INDEX_TYPE 0x8015
+
+/* glXQueryContext attributes */
+/* #define GLX_FBCONFIG_ID 0x8013 */
+/* #define GLX_RENDER_TYPE 0x8011 */
+#define GLX_SCREEN 0x800C
+
+/* glXSelectEvent event mask bits */
+#define GLX_PBUFFER_CLOBBER_MASK 0x08000000
+
+/* GLXPbufferClobberEvent event_type values */
+#define GLX_DAMAGED 0x8020
+#define GLX_SAVED 0x8021
+
+/* GLXPbufferClobberEvent draw_type values */
+#define GLX_WINDOW 0x8022
+#define GLX_PBUFFER 0x8023
+
+/* GLXPbufferClobberEvent buffer_mask bits */
+#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001
+#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002
+#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004
+#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008
+#define GLX_AUX_BUFFERS_BIT 0x00000010
+#define GLX_DEPTH_BUFFER_BIT 0x00000020
+#define GLX_STENCIL_BUFFER_BIT 0x00000040
+#define GLX_ACCUM_BUFFER_BIT 0x00000080
/*
** Extension return values from glXGetConfig. These are also
@@ -71,27 +179,27 @@ extern "C" {
#define GLX_X_VISUAL_TYPE_EXT 0x22 /* visual_info extension type */
#define GLX_TRANSPARENT_TYPE_EXT 0x23 /* visual_info extension */
#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 /* visual_info extension */
-#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 /* visual_info extension */
+#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 /* visual_info extension */
#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 /* visual_info extension */
-#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 /* visual_info extension */
+#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 /* visual_info extension */
#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 /* visual_info extension */
/* Property values for visual_type */
-#define GLX_TRUE_COLOR_EXT 0x8002
-#define GLX_DIRECT_COLOR_EXT 0x8003
-#define GLX_PSEUDO_COLOR_EXT 0x8004
-#define GLX_STATIC_COLOR_EXT 0x8005
-#define GLX_GRAY_SCALE_EXT 0x8006
-#define GLX_STATIC_GRAY_EXT 0x8007
+#define GLX_TRUE_COLOR_EXT 0x8002
+#define GLX_DIRECT_COLOR_EXT 0x8003
+#define GLX_PSEUDO_COLOR_EXT 0x8004
+#define GLX_STATIC_COLOR_EXT 0x8005
+#define GLX_GRAY_SCALE_EXT 0x8006
+#define GLX_STATIC_GRAY_EXT 0x8007
/* Property values for transparent pixel */
-#define GLX_NONE_EXT 0x8000
-#define GLX_TRANSPARENT_RGB_EXT 0x8008
-#define GLX_TRANSPARENT_INDEX_EXT 0x8009
+#define GLX_NONE_EXT 0x8000
+#define GLX_TRANSPARENT_RGB_EXT 0x8008
+#define GLX_TRANSPARENT_INDEX_EXT 0x8009
/* Property values for visual_rating */
-#define GLX_VISUAL_CAVEAT_EXT 0x20 /* visual_rating extension type */
-#define GLX_SLOW_VISUAL_EXT 0x8001
+#define GLX_VISUAL_CAVEAT_EXT 0x20 /* visual_rating extension type */
+#define GLX_SLOW_VISUAL_EXT 0x8001
#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
/*
@@ -109,11 +217,12 @@ extern "C" {
#define GLX_SCREEN_EXT 0x800C /* screen number */
/* GLX Extension Strings */
-#define GLX_EXT_import_context 1
-#define GLX_EXT_visual_info 1
-#define GLX_EXT_visual_rating 1
+#define GLX_EXT_import_context 1
+#define GLX_EXT_visual_info 1
+#define GLX_EXT_visual_rating 1
#define GLX_ARB_get_proc_address 1
+
#ifdef __cplusplus
}
#endif
diff --git a/xc/lib/GL/Imakefile b/xc/lib/GL/Imakefile
index dfc8231d2..c882109e1 100644
--- a/xc/lib/GL/Imakefile
+++ b/xc/lib/GL/Imakefile
@@ -134,6 +134,22 @@ REQUIREDLIBS += -lglide3x
GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src
+#elif GlxBuiltInR128
+
+ R128OBJS = mesa/src/drv/r128/?*.o
+ R128UOBJS = mesa/src/drv/r128/unshared/?*.o
+ R128DOBJS = mesa/src/drv/r128/debugger/?*.o
+ R128POBJS = mesa/src/drv/r128/profiled/?*.o
+ R128DONES = mesa/src/drv/r128/DONE
+
+ DRVOBJS = $(R128OBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS)
+ DRVUOBJS = $(R128UOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS)
+ DRVDOBJS = $(R128DOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS)
+ DRVPOBJS = $(R128POBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS)
+ DRVDONES = $(R128DONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES)
+
+ GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src
+
#elif GlxBuiltInMesa
#ifndef GlxDriverUsesMesa
diff --git a/xc/lib/GL/dri/XF86dri.c b/xc/lib/GL/dri/XF86dri.c
index 51615556a..dd0ee56ff 100644
--- a/xc/lib/GL/dri/XF86dri.c
+++ b/xc/lib/GL/dri/XF86dri.c
@@ -276,7 +276,7 @@ Bool XF86DRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
*ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
if (rep.length) {
- if (!(*clientDriverName = (char *)Xcalloc(rep.length + 1, 1))) {
+ if (!(*clientDriverName = (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
_XEatData(dpy, ((rep.clientDriverNameLength+3) & ~3));
return False;
}
diff --git a/xc/lib/GL/dri/drm/Imakefile b/xc/lib/GL/dri/drm/Imakefile
index 18619461b..42b6202d6 100644
--- a/xc/lib/GL/dri/drm/Imakefile
+++ b/xc/lib/GL/dri/drm/Imakefile
@@ -12,12 +12,17 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
DEFINES = $(ALLOC_DEFINES)
INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) -I.
- SRCS = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c
- OBJS = xf86drm.o xf86drmHash.o xf86drmRandom.o xf86drmSL.o
+ SRCS = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c \
+ xf86drmR128.c
+ OBJS = xf86drm.o xf86drmHash.o xf86drmRandom.o xf86drmSL.o \
+ xf86drmR128.o
#if defined(LinuxArchitecture)
OS_SUBDIR = linux
#endif
+#if defined(FreeBSDArchitecture)
+OS_SUBDIR = bsd
+#endif
LinkSourceFile(xf86drm.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm)
LinkSourceFile(xf86drmHash.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm)
@@ -25,6 +30,11 @@ LinkSourceFile(xf86drmRandom.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm)
LinkSourceFile(xf86drmSL.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm)
LinkSourceFile(xf86drm.h,$(XF86OSSRC))
LinkSourceFile(drm.h,$(XF86OSSRC)/$(OS_SUBDIR)/drm/kernel)
+LinkSourceFile(mga_drm.h,$(XF86OSSRC)/$(OS_SUBDIR)/drm/kernel)
+LinkSourceFile(i810_drm.h,$(XF86OSSRC)/$(OS_SUBDIR)/drm/kernel)
+LinkSourceFile(xf86drmR128.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm)
+LinkSourceFile(xf86drmR128.h,$(XF86OSSRC))
+LinkSourceFile(r128_drm.h,$(XF86OSSRC)/$(OS_SUBDIR)/drm/kernel)
#include <Library.tmpl>
diff --git a/xc/lib/GL/mesa/src/Imakefile b/xc/lib/GL/mesa/src/Imakefile
index 7d9b1d8e8..1d42b4950 100644
--- a/xc/lib/GL/mesa/src/Imakefile
+++ b/xc/lib/GL/mesa/src/Imakefile
@@ -348,8 +348,12 @@ LinkSourceFile(zoom.h, ../../../../extras/Mesa/src)
#ifdef i386Architecture
ASM_SRCS =
ASM_OBJS =
+#ifdef MesaUse3DNow
+ ASM_DEFS = -DUSE_MMX_ASM -DUSE_X86_ASM -DUSE_3DNOW_ASM
+#else
ASM_DEFS = -DUSE_MMX_ASM -DUSE_X86_ASM
#endif
+#endif
DEFINES = $(ALLOC_DEFINES) GlxDefines $(TDFX_DEFS) $(ASM_DEFS)
INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) -I../include -I../../dri -I. -I../../../../include
diff --git a/xc/lib/GL/mesa/src/X86/Imakefile b/xc/lib/GL/mesa/src/X86/Imakefile
index 858f0cd73..53402ac67 100644
--- a/xc/lib/GL/mesa/src/X86/Imakefile
+++ b/xc/lib/GL/mesa/src/X86/Imakefile
@@ -16,7 +16,6 @@ LinkSourceFile(x86.h, ../../../../../extras/Mesa/src/X86)
LinkSourceFile(x86a.S, ../../../../../extras/Mesa/src/X86)
LinkSourceFile(vertex.S, ../../../../../extras/Mesa/src/X86)
LinkSourceFile(x86flatregs.m4, ../../../../../extras/Mesa/src/X86)
-LinkSourceFile(x86a.S.m4, ../../../../../extras/Mesa/src/X86)
LinkSourceFile(mmx.h, ../../../../../extras/Mesa/src/X86)
LinkSourceFile(mmx_blend.S, ../../../../../extras/Mesa/src/X86)
@@ -55,9 +54,7 @@ XCOMM We'll learn at runtime whether 3dNow, MMX, etc are really present.
MMX_DEFS = -DUSE_MMX_ASM
-
-XCOMM Disabling 3DNow code for the time being
-#if 0
+#ifdef MesaUse3DNow
3DNOW_SRCS = 3dnow.c 3dnow_norm_raw.S 3dnow_xform_masked1.S \
3dnow_xform_masked2.S 3dnow_xform_masked3.S \
3dnow_xform_masked4.S 3dnow_xform_raw1.S \
@@ -73,6 +70,7 @@ XCOMM Disabling 3DNow code for the time being
3DNOW_DEFS = -DUSE_3DNOW_ASM
#endif
+
#endif
DEFINES = $(ALLOC_DEFINES) GlxDefines -DFX $(X86_DEFS) $(MMX_DEFS) $(3DNOW_DEFS)
@@ -96,7 +94,7 @@ STD_CPP_DEFINES = StandardDefines $(PROJECT_DEFINES)
SubdirLibraryRule($(OBJS))
NormalLintTarget($(SRCS))
-#ifdef HAVE_3DNOW
+#ifdef MesaUse3DNow
ObjectFromAsmSource(3dnow_norm_raw, NullParameter)
ObjectFromAsmSource(3dnow_xform_masked1, NullParameter)
ObjectFromAsmSource(3dnow_xform_masked2, NullParameter)
@@ -109,9 +107,7 @@ ObjectFromAsmSource(3dnow_xform_raw4, NullParameter)
ObjectFromAsmSource(vertex_3dnow, NullParameter)
#endif
-#ifdef HAVE_MMX
ObjectFromAsmSource(mmx_blend, NullParameter)
-#endif
ObjectFromAsmSource(common_x86asm, NullParameter)
ObjectFromAsmSource(vertex, NullParameter)
@@ -119,6 +115,3 @@ ObjectFromAsmSource(x86a, NullParameter)
DependTarget()
-x86a.S: x86flatregs.m4
-x86a.S: x86a.S.m4
- m4 $< >$@
diff --git a/xc/lib/GL/mesa/src/drv/Imakefile b/xc/lib/GL/mesa/src/drv/Imakefile
index fadb29bb2..ed30e7196 100644
--- a/xc/lib/GL/mesa/src/drv/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/Imakefile
@@ -16,6 +16,15 @@ DRIVER += gamma
#if GlxBuiltInTdfx
DRIVER += tdfx
#endif
+#if GlxBuiltInMga
+DRIVER += common mga
+#endif
+#if GlxBuiltInI810
+DRIVER += common i810
+#endif
+#if GlxBuiltInR128
+DRIVER += r128
+#endif
SUBDIRS = $(DRIVER)
#else
@@ -23,6 +32,10 @@ SUBDIRS += gamma
#if HasGlide3
SUBDIRS += tdfx
#endif
+SUBDIRS += common
+SUBDIRS += mga
+SUBDIRS += i810
+SUBDIRS += r128
#endif
MakeSubdirs($(SUBDIRS))
diff --git a/xc/lib/GL/mesa/src/drv/common/Imakefile b/xc/lib/GL/mesa/src/drv/common/Imakefile
index 5c3d40dd7..d47b662e8 100644
--- a/xc/lib/GL/mesa/src/drv/common/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/common/Imakefile
@@ -22,13 +22,12 @@ MESA_INCLUDES = -I. -I.. -I../../include
DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES)
- INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) \
- -I/usr/include/glide
+ INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES)
DRISRCS = hwlog.c mm.c
DRIOBJS = hwlog.o mm.o
- SRCS = $(DRISRCS)
- OBJS = $(DRIOBJS)
+ SRCS = $(DRISRCS)
+ OBJS = $(DRIOBJS)
#if !GlxUseBuiltInDRIDriver
#undef DoNormalLib NormalLibGlx
@@ -44,7 +43,8 @@ LibraryObjectRule()
SubdirLibraryRule($(OBJS))
NormalLintTarget($(SRCS))
-#if !GlxUseBuiltInDRIDriver
+XCOMM #if !GlxUseBuiltInDRIDriver
+#if 0
LIBNAME = i810_dri.so
ALL_OBJS = $(OBJS)
ALL_DEPS = DONE
diff --git a/xc/lib/GL/mesa/src/drv/gamma/Imakefile b/xc/lib/GL/mesa/src/drv/gamma/Imakefile
index 05e35561e..0e9833177 100644
--- a/xc/lib/GL/mesa/src/drv/gamma/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/gamma/Imakefile
@@ -1,4 +1,5 @@
-XCOMM $XFree86: xc/lib/GL/mesa/src/drv/gamma/Imakefile,v 1.8 2000/03/02 16:07:35 martin Exp $
+
+#include <Threads.tmpl>
#define DoNormalLib NormalLibGlx
#define DoSharedLib SharedLibGlx
@@ -6,28 +7,35 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/gamma/Imakefile,v 1.8 2000/03/02 16:07:35
#define DoDebugLib DebugLibGlx
#define DoProfileLib ProfileLibGlx
-LinkSourceFile(xmesaP.h, ../../../../../../extras/Mesa/src/X)
-LinkSourceFile(glapi.h, ../../../../../../extras/Mesa/src)
-
-
#if Malloc0ReturnsNull
ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
#endif
#if BuildXF86DRI
- DRI_DEFINES = GlxDefines
+ DRI_DEFINES = GlxDefines -DDRIVERTS
DRI_INCLUDES = -I../../../../dri -I../../../../glx \
-I../../../dri \
-I$(TOP)/include -I$(TOP)/include/GL \
-I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri \
-I$(XF86DRIVERSRC)/glint \
- -I../../../include -I../.. -I../../X
+ -I../../../include -I../.. -I../../X -I../common \
+ -I$(XF86OSSRC)/linux/drm/kernel
#endif
MESA_INCLUDES = -I. -I.. -I../../include
+
+
DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES)
- INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES)
+ INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES)
+
+#if 0
+ LOSRC = ../../../../lowpc.c
+ LOOBJ = ../../../../lowpc.o
+
+ HISRC = ../../../../highpc.c
+ HIOBJ = ../../../../highpc.o
+#endif
DRISRCS = ../../../dri/dri_mesa.c \
../../../../dri/dri_tmm.c
@@ -46,16 +54,216 @@ MESA_INCLUDES = -I. -I.. -I../../include
../../../../dri/drm/xf86drmSL.o
GAMMASRCS = gamma_gl.c gamma_xmesa.c gamma_init.c gamma_matrix.c \
- gamma_inithw.c gamma_texture.c
+ gamma_inithw.c gamma_texture.c /* gamma_dlist.c */
GAMMAOBJS = gamma_gl.o gamma_xmesa.o gamma_init.o gamma_matrix.o \
- gamma_inithw.o gamma_texture.o
+ gamma_inithw.o gamma_texture.o /* gamma_dlist.o */
+
+ MESASRCS = ../../aatriangle.c \
+ ../../accum.c \
+ ../../alpha.c \
+ ../../alphabuf.c \
+ ../../attrib.c \
+ ../../bbox.c \
+ ../../bitmap.c \
+ ../../blend.c \
+ ../../buffers.c \
+ ../../clip.c \
+ ../../colortab.c \
+ ../../config.c \
+ ../../context.c \
+ ../../copypix.c \
+ ../../cva.c \
+ ../../debug_xform.c \
+ ../../depth.c \
+ ../../dlist.c \
+ ../../drawpix.c \
+ ../../enable.c \
+ ../../enums.c \
+ ../../eval.c \
+ ../../extensions.c \
+ ../../feedback.c \
+ ../../fog.c \
+ ../../get.c \
+ ../../glapi.c \
+ ../../glapinoop.c \
+ ../../glthread.c \
+ ../../hash.c \
+ ../../image.c \
+ ../../imaging.c \
+ ../../light.c \
+ ../../lines.c \
+ ../../logic.c \
+ ../../masking.c \
+ ../../matrix.c \
+ ../../mem.c \
+ ../../mmath.c \
+ ../../pb.c \
+ ../../pipeline.c \
+ ../../pixel.c \
+ ../../pixeltex.c \
+ ../../points.c \
+ ../../polygon.c \
+ ../../quads.c \
+ ../../rastpos.c \
+ ../../readpix.c \
+ ../../rect.c \
+ ../../scissor.c \
+ ../../shade.c \
+ ../../span.c \
+ ../../stages.c \
+ ../../state.c \
+ ../../stencil.c \
+ ../../teximage.c \
+ ../../texobj.c \
+ ../../texstate.c \
+ ../../texture.c \
+ ../../texutil.c \
+ ../../translate.c \
+ ../../triangle.c \
+ ../../varray.c \
+ ../../vb.c \
+ ../../vbcull.c \
+ ../../vbfill.c \
+ ../../vbindirect.c \
+ ../../vbrender.c \
+ ../../vbxform.c \
+ ../../vector.c \
+ ../../vertices.c \
+ ../../winpos.c \
+ ../../xform.c \
+ ../../zoom.c \
+ ../../X86/common_x86.c
+
+ MESAOBJS = ../../aatriangle.o \
+ ../../accum.o \
+ ../../alpha.o \
+ ../../alphabuf.o \
+ ../../attrib.o \
+ ../../bbox.o \
+ ../../bitmap.o \
+ ../../blend.o \
+ ../../buffers.o \
+ ../../clip.o \
+ ../../colortab.o \
+ ../../config.o \
+ ../../context.o \
+ ../../copypix.o \
+ ../../cva.o \
+ ../../debug_xform.o \
+ ../../depth.o \
+ ../../dlist.o \
+ ../../drawpix.o \
+ ../../enable.o \
+ ../../enums.o \
+ ../../eval.o \
+ ../../extensions.o \
+ ../../feedback.o \
+ ../../fog.o \
+ ../../get.o \
+ ../../hash.o \
+ ../../hint.o \
+ ../../image.o \
+ ../../imaging.o \
+ ../../light.o \
+ ../../lines.o \
+ ../../logic.o \
+ ../../masking.o \
+ ../../matrix.o \
+ ../../mem.o \
+ ../../mmath.o \
+ ../../pb.o \
+ ../../pipeline.o \
+ ../../pixel.o \
+ ../../pixeltex.o \
+ ../../points.o \
+ ../../polygon.o \
+ ../../quads.o \
+ ../../rastpos.o \
+ ../../readpix.o \
+ ../../rect.o \
+ ../../scissor.o \
+ ../../shade.o \
+ ../../span.o \
+ ../../stages.o \
+ ../../state.o \
+ ../../stencil.o \
+ ../../teximage.o \
+ ../../texobj.o \
+ ../../texstate.o \
+ ../../texture.o \
+ ../../texutil.o \
+ ../../translate.o \
+ ../../triangle.o \
+ ../../varray.o \
+ ../../vb.o \
+ ../../vbcull.o \
+ ../../vbfill.o \
+ ../../vbindirect.o \
+ ../../vbrender.o \
+ ../../vbxform.o \
+ ../../vector.o \
+ ../../vertices.o \
+ ../../winpos.o \
+ ../../xform.o \
+ ../../zoom.o
+
+#ifdef i386Architecture
+ X86_SRCS = ../../X86/x86.c \
+ ../../X86/x86a.S \
+ ../../X86/common_x86.c \
+ ../../X86/common_x86asm.S \
+ ../../X86/vertex.S
-XCOMM SRCS = $(DRISRCS) $(DRMSRCS) $(GAMMASRCS)
-XCOMM OBJS = $(DRIOBJS) $(DRMOBJS) $(GAMMAOBJS)
+ X86_OBJS = ../../X86/x86.o \
+ ../../X86/x86a.o \
+ ../../X86/common_x86.o \
+ ../../X86/common_x86asm.o \
+ ../../X86/vertex.o
- SRCS = $(GAMMASRCS)
- OBJS = $(DRIOBJS) $(DRMOBJS) $(GAMMAOBJS)
+ MMX_SRCS = ../../X86/mmx_blend.S
+
+ MMX_OBJS = ../../X86/mmx_blend.o
+
+XCOMM Disabling 3Dnow code for the time being.
+#if 0
+ 3DNOW_SRCS = ../../X86/3dnow.c \
+ ../../X86/3dnow_norm_raw.S \
+ ../../X86/3dnow_xform_masked1.S \
+ ../../X86/3dnow_xform_masked2.S \
+ ../../X86/3dnow_xform_masked3.S \
+ ../../X86/3dnow_xform_masked4.S \
+ ../../X86/3dnow_xform_raw1.S \
+ ../../X86/3dnow_xform_raw2.S \
+ ../../X86/3dnow_xform_raw3.S \
+ ../../X86/3dnow_xform_raw4.S \
+ ../../X86/vertex_3dnow.S
+
+ 3DNOW_OBJS = ../../X86/3dnow.o \
+ ../../X86/3dnow_norm_raw.o \
+ ../../X86/3dnow_xform_masked1.o \
+ ../../X86/3dnow_xform_masked2.o \
+ ../../X86/3dnow_xform_masked3.o \
+ ../../X86/3dnow_xform_masked4.o \
+ ../../X86/3dnow_xform_raw1.o \
+ ../../X86/3dnow_xform_raw2.o \
+ ../../X86/3dnow_xform_raw3.o \
+ ../../X86/3dnow_xform_raw4.o \
+ ../../X86/vertex_3dnow.o
+#endif
+
+#endif
+
+ ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS)
+ ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS)
+
+ SRCS = $(LOWSRC) $(DRISRCS) $(DRMSRCS) $(MESASRCS) $(ASMSRCS) $(GAMMASRCS) $(HISRC)
+ OBJS = $(LOWOBJ) $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) $(ASMOBJS) $(GAMMAOBJS) $(HIOBJ)
+
+REQUIREDLIBS += -lm
+#if !GlxBuiltInMga
+REQUIREDLIBS += -L../../../.. -lGL
+#endif
#if !GlxUseBuiltInDRIDriver
diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_gl.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_gl.c
index d72c642cf..61e59a7a9 100644
--- a/xc/lib/GL/mesa/src/drv/gamma/gamma_gl.c
+++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_gl.c
@@ -30,13 +30,16 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* Authors:
* Kevin E. Martin <kevin@precisioninsight.com>
* Brian Paul <brian@precisioninsight.com>
+ * Alan Hourihane <Alan.Hourihane@btinternet.com>
*/
#ifdef GLX_DIRECT_RENDERING
+#include <Xarch.h>
#include <math.h>
#include "gamma_gl.h"
#include "gamma_init.h"
+#include "glint_dri.h"
#ifdef RANDOMIZE_COLORS
#include <stdlib.h>
#endif
@@ -114,7 +117,7 @@ void _gamma_Begin(GLenum mode)
DEBUG_GLCMDS(("Begin: %04x\n", (int)mode));
if ((gCCPriv->Begin & B_PrimType_Mask) != B_PrimType_Null) {
- /* ERROR!!! */
+ DEBUG_ERROR(("Begin: Error\n"));
return;
}
@@ -177,8 +180,9 @@ void _gamma_BindTexture(GLenum target, GLuint texture)
gCCPriv->curTexObj = gammaTOFind(texture);
/* Make the new texture images resident */
- if (!driTMMMakeImagesResident(gCCPriv->tmm, MIPMAP_LEVELS,
- gCCPriv->curTexObj->image, addrs)) {
+ if (driTMMMakeImagesResident(gCCPriv->tmm, MIPMAP_LEVELS,
+ gCCPriv->curTexObj->image, addrs) < 0) {
+ DEBUG_ERROR(("BindTexture: unable\n"));
/* NOT_DONE: Handle error */
}
@@ -358,8 +362,10 @@ void _gamma_CallLists(GLsizei n, GLenum type, const GLvoid *lists)
void _gamma_Clear(GLbitfield mask)
{
+ int temp;
unsigned int depth = 0;
int do_clear = 0;
+ GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)gCC->driScreenPriv->pDevPriv;
#ifdef DO_VALIDATE
__DRIscreenPrivate *driScrnPriv = gCC->driScreenPriv;
#endif
@@ -437,11 +443,12 @@ void _gamma_Clear(GLbitfield mask)
gCCPriv->FrameCount &= 0xff;
#endif
+ temp = (gCCPriv->LBReadMode & LBPartialProdMask) | LBWindowOriginBot;
+ /* UGH - move this later ! */
+ if (gDRIPriv->numMXDevices == 2) temp |= LBScanLineInt2;
+
CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
- WRITE(gCCPriv->buf, LBReadMode,
- ((gCCPriv->LBReadMode & LBPartialProdMask) |
- LBScanLineInt2 |
- LBWindowOriginBot));
+ WRITE(gCCPriv->buf, LBReadMode, temp);
/* Force FCP to be written */
CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
@@ -627,34 +634,48 @@ void _gamma_ClipPlane(GLenum plane, const GLdouble *equation)
void _gamma_Color3b(GLbyte red, GLbyte green, GLbyte blue)
{
+ GLfloat r,g,b;
+
DEBUG_GLCMDS(("Color3b: %d %d %d\n", red, green, blue));
+
+ r = BYTE_TO_FLOAT(red);
+ g = BYTE_TO_FLOAT(green);
+ b = BYTE_TO_FLOAT(blue);
+
+ _gamma_Color3f(r,g,b);
}
void _gamma_Color3bv(const GLbyte *v)
{
+ GLfloat p[3];
+
DEBUG_GLCMDS(("Color3bv: %d %d %d\n", v[0], v[1], v[2]));
+
+ p[0] = BYTE_TO_FLOAT(v[0]);
+ p[1] = BYTE_TO_FLOAT(v[1]);
+ p[2] = BYTE_TO_FLOAT(v[2]);
+
+ _gamma_Color3fv(p);
}
void _gamma_Color3d(GLdouble red, GLdouble green, GLdouble blue)
{
DEBUG_GLCMDS(("Color3d: %f %f %f\n", red, green, blue));
+
+ _gamma_Color3f((GLfloat)red,(GLfloat)green,(GLfloat)blue);
}
void _gamma_Color3dv(const GLdouble *v)
{
DEBUG_GLCMDS(("Color3dv: %f %f %f\n", v[0], v[1], v[2]));
+
+ _gamma_Color3fv((GLfloat*)v);
}
void _gamma_Color3f(GLfloat red, GLfloat green, GLfloat blue)
{
DEBUG_GLCMDS(("Color3f: %f %f %f\n", red, green, blue));
-#ifdef RANDOMIZE_COLORS
- red = (random() / (double)RAND_MAX);
- green = (random() / (double)RAND_MAX);
- blue = (random() / (double)RAND_MAX);
-#endif
-
CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
WRITEF(gCCPriv->buf, Cb, blue);
WRITEF(gCCPriv->buf, Cg, green);
@@ -665,107 +686,188 @@ void _gamma_Color3fv(const GLfloat *v)
{
DEBUG_GLCMDS(("Color3fv: %f %f %f\n", v[0], v[1], v[2]));
-#ifdef RANDOMIZE_COLORS
- {
- float r, g, b;
- r = (random() / (double)RAND_MAX);
- g = (random() / (double)RAND_MAX);
- b = (random() / (double)RAND_MAX);
- CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
- WRITEF(gCCPriv->buf, Cb, b);
- WRITEF(gCCPriv->buf, Cg, g);
- WRITEF(gCCPriv->buf, Cr3, r);
- }
-#else
CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
WRITEF(gCCPriv->buf, Cb, v[2]);
WRITEF(gCCPriv->buf, Cg, v[1]);
WRITEF(gCCPriv->buf, Cr3, v[0]);
-#endif
}
void _gamma_Color3i(GLint red, GLint green, GLint blue)
{
+ GLfloat r,g,b;
+
DEBUG_GLCMDS(("Color3i: %d %d %d\n", (int)red, (int)green, (int)blue));
+
+ r = INT_TO_FLOAT(red);
+ g = INT_TO_FLOAT(green);
+ b = INT_TO_FLOAT(blue);
+
+ _gamma_Color3f(r,g,b);
}
void _gamma_Color3iv(const GLint *v)
{
+ GLfloat p[3];
+
DEBUG_GLCMDS(("Color3iv: %d %d %d\n", (int)v[0], (int)v[1], (int)v[2]));
+
+ p[0] = INT_TO_FLOAT(v[0]);
+ p[1] = INT_TO_FLOAT(v[1]);
+ p[2] = INT_TO_FLOAT(v[2]);
+
+ _gamma_Color3fv(p);
}
void _gamma_Color3s(GLshort red, GLshort green, GLshort blue)
{
+ GLfloat r,g,b;
+
DEBUG_GLCMDS(("Color3s: %d %d %d\n", red, green, blue));
+
+ r = SHORT_TO_FLOAT(red);
+ g = SHORT_TO_FLOAT(green);
+ b = SHORT_TO_FLOAT(blue);
+
+ _gamma_Color3f(r,g,b);
}
void _gamma_Color3sv(const GLshort *v)
{
+ GLfloat p[3];
+
DEBUG_GLCMDS(("Color3sv: %d %d %d\n", v[0], v[1], v[2]));
+
+ p[0] = SHORT_TO_FLOAT(v[0]);
+ p[1] = SHORT_TO_FLOAT(v[1]);
+ p[2] = SHORT_TO_FLOAT(v[2]);
+
+ _gamma_Color3fv(p);
}
void _gamma_Color3ub(GLubyte red, GLubyte green, GLubyte blue)
{
+ GLuint c;
+
DEBUG_GLCMDS(("Color3ub: %d %d %d\n", red, green, blue));
+
+ c = (blue << 16) | (green << 8) | red;
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, PackedColor3, c);
}
void _gamma_Color3ubv(const GLubyte *v)
{
+ GLuint c;
+
DEBUG_GLCMDS(("Color3ubv: %d %d %d\n", v[0], v[1], v[2]));
+
+ c = (v[2] << 16) | (v[1] << 8) | v[0];
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, PackedColor3, c);
}
void _gamma_Color3ui(GLuint red, GLuint green, GLuint blue)
{
+ GLfloat r,g,b;
+
DEBUG_GLCMDS(("Color3ui: %d %d %d\n",
(unsigned int)red, (unsigned int)green, (unsigned int)blue));
+
+ r = UINT_TO_FLOAT(red);
+ g = UINT_TO_FLOAT(green);
+ b = UINT_TO_FLOAT(blue);
+
+ _gamma_Color3f(r,g,b);
}
void _gamma_Color3uiv(const GLuint *v)
{
+ GLfloat p[3];
+
DEBUG_GLCMDS(("Color3uiv: %d %d %d\n",
(unsigned int)v[0], (unsigned int)v[1], (unsigned int)v[2]));
+
+ p[0] = UINT_TO_FLOAT(v[0]);
+ p[1] = UINT_TO_FLOAT(v[1]);
+ p[2] = UINT_TO_FLOAT(v[2]);
+
+ _gamma_Color3fv(p);
}
void _gamma_Color3us(GLushort red, GLushort green, GLushort blue)
{
+ GLuint c;
+
DEBUG_GLCMDS(("Color3us: %d %d %d\n", red, green, blue));
+
+ c = (USHORT_TO_UBYTE(blue) << 16) | (USHORT_TO_UBYTE(green) << 8) |
+ USHORT_TO_UBYTE(red);
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, PackedColor3, c);
}
void _gamma_Color3usv(const GLushort *v)
{
+ GLuint c;
+
DEBUG_GLCMDS(("Color3usv: %d %d %d\n", v[0], v[1], v[2]));
+
+ c = (USHORT_TO_UBYTE(v[2]) << 16) | (USHORT_TO_UBYTE(v[1]) << 8) |
+ USHORT_TO_UBYTE(v[0]);
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, PackedColor3, c);
}
void _gamma_Color4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)
{
+ GLfloat r,g,b,a;
+
DEBUG_GLCMDS(("Color4b: %d %d %d %d\n", red, green, blue, alpha));
+
+ r = BYTE_TO_FLOAT(red);
+ g = BYTE_TO_FLOAT(green);
+ b = BYTE_TO_FLOAT(blue);
+ a = BYTE_TO_FLOAT(alpha);
+
+ _gamma_Color4f(r,g,b,a);
}
void _gamma_Color4bv(const GLbyte *v)
{
+ GLfloat p[4];
+
DEBUG_GLCMDS(("Color4bv: %d %d %d %d\n", v[0], v[1], v[2], v[3]));
+
+ p[0] = BYTE_TO_FLOAT(v[0]);
+ p[1] = BYTE_TO_FLOAT(v[1]);
+ p[2] = BYTE_TO_FLOAT(v[2]);
+ p[3] = BYTE_TO_FLOAT(v[3]);
+
+ _gamma_Color4fv(p);
}
void _gamma_Color4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
{
DEBUG_GLCMDS(("Color4d: %f %f %f %f\n", red, green, blue, alpha));
+
+ _gamma_Color4f((GLfloat)red,(GLfloat)green,(GLfloat)blue,(GLfloat)alpha);
}
void _gamma_Color4dv(const GLdouble *v)
{
DEBUG_GLCMDS(("Color4dv: %f %f %f %f\n", v[0], v[1], v[2], v[3]));
+
+ _gamma_Color4fv((GLfloat*)v);
}
void _gamma_Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
DEBUG_GLCMDS(("Color4f: %f %f %f %f\n", red, green, blue, alpha));
-#ifdef RANDOMIZE_COLORS
- red = (random() / (double)RAND_MAX);
- green = (random() / (double)RAND_MAX);
- blue = (random() / (double)RAND_MAX);
-#endif
-
CHECK_DMA_BUFFER(gCC, gCCPriv, 4);
WRITEF(gCCPriv->buf, Ca, alpha);
WRITEF(gCCPriv->buf, Cb, blue);
@@ -777,37 +879,41 @@ void _gamma_Color4fv(const GLfloat *v)
{
DEBUG_GLCMDS(("Color4fv: %f %f %f %f\n", v[0], v[1], v[2], v[3]));
-#ifdef RANDOMIZE_COLORS
- {
- float r, g, b;
- r = (random() / (double)RAND_MAX);
- g = (random() / (double)RAND_MAX);
- b = (random() / (double)RAND_MAX);
- CHECK_DMA_BUFFER(gCC, gCCPriv, 4);
- WRITEF(gCCPriv->buf, Ca, v[3]);
- WRITEF(gCCPriv->buf, Cb, b);
- WRITEF(gCCPriv->buf, Cg, g);
- WRITEF(gCCPriv->buf, Cr3, r);
- }
-#else
CHECK_DMA_BUFFER(gCC, gCCPriv, 4);
WRITEF(gCCPriv->buf, Ca, v[3]);
WRITEF(gCCPriv->buf, Cb, v[2]);
WRITEF(gCCPriv->buf, Cg, v[1]);
WRITEF(gCCPriv->buf, Cr4, v[0]);
-#endif
}
void _gamma_Color4i(GLint red, GLint green, GLint blue, GLint alpha)
{
+ GLfloat r,g,b,a;
+
DEBUG_GLCMDS(("Color4i: %d %d %d %d\n", (int)red, (int)green, (int)blue,
(int)alpha));
+
+ r = INT_TO_FLOAT(red);
+ g = INT_TO_FLOAT(green);
+ b = INT_TO_FLOAT(blue);
+ a = INT_TO_FLOAT(alpha);
+
+ _gamma_Color4f(r,g,b,a);
}
void _gamma_Color4iv(const GLint *v)
{
+ GLfloat p[4];
+
DEBUG_GLCMDS(("Color4iv: %d %d %d %d\n", (int)v[0], (int)v[1], (int)v[2],
(int)v[3]));
+
+ p[0] = INT_TO_FLOAT(v[0]);
+ p[1] = INT_TO_FLOAT(v[1]);
+ p[2] = INT_TO_FLOAT(v[2]);
+ p[3] = INT_TO_FLOAT(v[3]);
+
+ _gamma_Color4fv(p);
}
void _gamma_Color4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)
@@ -826,11 +932,7 @@ void _gamma_Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
DEBUG_GLCMDS(("Color4ub: %d %d %d %d\n", red, green, blue, alpha));
-#ifdef RANDOMIZE_COLORS
- c = (random() / (double)RAND_MAX) * 16777216;
-#else
c = (alpha << 24) | (blue << 16) | (green << 8) | red;
-#endif
CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
WRITE(gCCPriv->buf, PackedColor4, c);
@@ -842,17 +944,7 @@ void _gamma_Color4ubv(const GLubyte *v)
DEBUG_GLCMDS(("Color4ubv: %d %d %d %d\n", v[0], v[1], v[2], v[3]));
-#ifdef RANDOMIZE_COLORS
- c = (random() / (double)RAND_MAX) * 16777216;
-#else
-/* NOT_DONE: Is there a standard define for endianness? */
-#define IS_LITTLE_ENDIAN 1
-#if IS_LITTLE_ENDIAN
- c = *((GLuint *)v);
-#else
c = (v[3] << 24) | (v[2] << 16) | (v[1] << 8) | v[0];
-#endif
-#endif
CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
WRITE(gCCPriv->buf, PackedColor4, c);
@@ -890,6 +982,43 @@ void _gamma_ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean
void _gamma_ColorMaterial(GLenum face, GLenum mode)
{
DEBUG_GLCMDS(("ColorMaterial: %04x %04x\n", (int)face, (int)mode));
+
+ gCCPriv->MaterialMode &= ~MaterialModeEnable;
+ gCCPriv->ColorMaterialMode = ColorMaterialModeDisable;
+
+ switch (face) {
+ case GL_FRONT:
+ gCCPriv->ColorMaterialMode |= ColorMaterialModeFront;
+ break;
+ case GL_BACK:
+ gCCPriv->ColorMaterialMode |= ColorMaterialModeBack;
+ break;
+ case GL_FRONT_AND_BACK:
+ gCCPriv->ColorMaterialMode |= ColorMaterialModeFrontAndBack;
+ break;
+ }
+
+ switch (mode) {
+ case GL_AMBIENT:
+ gCCPriv->ColorMaterialMode |= ColorMaterialModeAmbient;
+ break;
+ case GL_EMISSION:
+ gCCPriv->ColorMaterialMode |= ColorMaterialModeEmission;
+ break;
+ case GL_DIFFUSE:
+ gCCPriv->ColorMaterialMode |= ColorMaterialModeDiffuse;
+ break;
+ case GL_SPECULAR:
+ gCCPriv->ColorMaterialMode |= ColorMaterialModeSpecular;
+ break;
+ case GL_AMBIENT_AND_DIFFUSE:
+ gCCPriv->ColorMaterialMode |= ColorMaterialModeAmbAndDiff;
+ break;
+ }
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
+ WRITE(gCCPriv->buf, ColorMaterialMode, gCCPriv->ColorMaterialMode);
+ WRITE(gCCPriv->buf, MaterialMode, gCCPriv->MaterialMode);
}
void _gamma_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
@@ -938,9 +1067,6 @@ void _gamma_CullFace(GLenum mode)
gCCPriv->GeometryMode &= ~GM_PolyCullMask;
-#ifdef CULL_ALL_PRIMS
- gCCPriv->GeometryMode |= GM_PolyCullBoth;
-#else
switch (mode) {
case GL_FRONT:
gCCPriv->GeometryMode |= GM_PolyCullFront;
@@ -955,7 +1081,7 @@ void _gamma_CullFace(GLenum mode)
/* ERROR!! */
break;
}
-#endif
+
CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
WRITE(gCCPriv->buf, GeometryMode, gCCPriv->GeometryMode);
}
@@ -980,7 +1106,8 @@ void _gamma_DeleteTextures(GLsizei n, const GLuint *textures)
for (i = 0; i < n; i++) {
gammaTexObj *t = gammaTOFind(textures[i]);
- if (!driTMMDeleteImages(gCCPriv->tmm, MIPMAP_LEVELS, t->image)) {
+ if (driTMMDeleteImages(gCCPriv->tmm, MIPMAP_LEVELS, t->image) < 0) {
+ DEBUG_ERROR(("DeleteTextures: unable\n"));
/* NOT_DONE: Handle error */
}
gammaTODelete(textures[i]);
@@ -1068,11 +1195,9 @@ void _gamma_Disable(GLenum cap)
switch (cap) {
case GL_CULL_FACE:
-#ifdef CULL_ALL_PRIMS
gCCPriv->GeometryMode &= ~GM_PolyCullEnable;
CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
WRITE(gCCPriv->buf, GeometryMode, gCCPriv->GeometryMode);
-#endif
break;
case GL_DEPTH_TEST:
if (gCCPriv->Flags & GAMMA_DEPTH_BUFFER) {
@@ -1106,6 +1231,35 @@ void _gamma_Disable(GLenum cap)
WRITE(gCCPriv->buf, FBReadMode, (gCCPriv->FBReadMode |
gCCPriv->AB_FBReadMode));
break;
+ case GL_COLOR_MATERIAL:
+ gCCPriv->ColorMaterialMode &= ~ColorMaterialModeEnable;
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, ColorMaterialMode, gCCPriv->ColorMaterialMode);
+ break;
+ case GL_FOG:
+ gCCPriv->Begin &= ~B_FogEnable;
+ gCCPriv->GeometryMode &= ~GM_FogEnable;
+ gCCPriv->DeltaMode &= ~DM_FogEnable;
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
+ WRITE(gCCPriv->buf, GeometryMode, gCCPriv->GeometryMode);
+ WRITE(gCCPriv->buf, DeltaMode, gCCPriv->DeltaMode);
+ WRITE(gCCPriv->buf, FogMode, FogModeDisable);
+ break;
+ case GL_LIGHTING:
+ gCCPriv->LightingMode &= ~LightingModeEnable;
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, LightingMode, gCCPriv->LightingMode);
+ break;
+ case GL_LIGHT0:
+ gCCPriv->Light0Mode &= ~LNM_On;
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, Light0Mode, gCCPriv->Light0Mode);
+ break;
+ case GL_LIGHT1:
+ gCCPriv->Light1Mode &= ~LNM_On;
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, Light1Mode, gCCPriv->Light1Mode);
+ break;
case GL_TEXTURE_2D:
gCCPriv->Texture2DEnabled = GL_FALSE;
gCCPriv->Begin &= ~B_TextureEnable;
@@ -1227,6 +1381,35 @@ void _gamma_Enable(GLenum cap)
WRITE(gCCPriv->buf, FBReadMode, (gCCPriv->FBReadMode |
gCCPriv->AB_FBReadMode));
break;
+ case GL_COLOR_MATERIAL:
+ gCCPriv->ColorMaterialMode |= ColorMaterialModeEnable;
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, ColorMaterialMode, gCCPriv->ColorMaterialMode);
+ break;
+ case GL_FOG:
+ gCCPriv->Begin |= B_FogEnable;
+ gCCPriv->GeometryMode |= GM_FogEnable;
+ gCCPriv->DeltaMode |= DM_FogEnable;
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
+ WRITE(gCCPriv->buf, GeometryMode, gCCPriv->GeometryMode);
+ WRITE(gCCPriv->buf, DeltaMode, gCCPriv->DeltaMode);
+ WRITE(gCCPriv->buf, FogMode, FogModeEnable);
+ break;
+ case GL_LIGHTING:
+ gCCPriv->LightingMode |= LightingModeEnable | 16<<6;
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, LightingMode, gCCPriv->LightingMode);
+ break;
+ case GL_LIGHT0:
+ gCCPriv->Light0Mode |= LNM_On;
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, Light0Mode, gCCPriv->Light0Mode);
+ break;
+ case GL_LIGHT1:
+ gCCPriv->Light1Mode |= LNM_On;
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, Light1Mode, gCCPriv->Light1Mode);
+ break;
case GL_TEXTURE_2D:
gCCPriv->Texture2DEnabled = GL_TRUE;
#ifndef TURN_OFF_TEXTURES
@@ -1294,34 +1477,42 @@ void _gamma_EvalCoord1d(GLdouble u)
void _gamma_EvalCoord1dv(const GLdouble *u)
{
+ DEBUG_GLCMDS(("EvalCoord1dv: %f\n", *u));
}
void _gamma_EvalCoord1f(GLfloat u)
{
+ DEBUG_GLCMDS(("EvalCoord1f: %f\n", u));
}
void _gamma_EvalCoord1fv(const GLfloat *u)
{
+ DEBUG_GLCMDS(("EvalCoord1fv: %f\n", *u));
}
void _gamma_EvalCoord2d(GLdouble u, GLdouble v)
{
+ DEBUG_GLCMDS(("EvalCoord2d: %f %f\n", u, v));
}
void _gamma_EvalCoord2dv(const GLdouble *u)
{
+ DEBUG_GLCMDS(("EvalCoord2dv: %f %f\n", u[0], u[1]));
}
void _gamma_EvalCoord2f(GLfloat u, GLfloat v)
{
+ DEBUG_GLCMDS(("EvalCoord2f: %f %f\n", u, v));
}
void _gamma_EvalCoord2fv(const GLfloat *u)
{
+ DEBUG_GLCMDS(("EvalCoord1fv: %f %f\n", u[0], u[1]));
}
void _gamma_EvalMesh1(GLenum mode, GLint i1, GLint i2)
{
+ DEBUG_GLCMDS(("EvalMesh1: %d %d %d\n", mode, i1, i2));
}
void _gamma_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
@@ -1358,16 +1549,55 @@ void _gamma_Flush(void)
void _gamma_Fogf(GLenum pname, GLfloat param)
{
DEBUG_GLCMDS(("Fogf: %04x %f\n", (int)pname, param));
+
+ switch (pname) {
+ case GL_FOG_DENSITY:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITEF(gCCPriv->buf, FogDensity, param);
+ break;
+ }
}
void _gamma_Fogfv(GLenum pname, const GLfloat *params)
{
+ int color;
+
DEBUG_GLCMDS(("Fogfv: %04x %f\n", (int)pname, *params));
+
+ switch (pname) {
+ case GL_FOG_COLOR:
+ color = ((int)params[3]<<24) | ((int)params[2]<<16) |
+ ((int)params[1]<<8) | ((int)params[0]);
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, FogColor, color);
+ break;
+ }
}
void _gamma_Fogi(GLenum pname, GLint param)
{
DEBUG_GLCMDS(("Fogi: %04x %d\n", (int)pname, (int)param));
+
+ gCCPriv->GeometryMode &= ~GM_FogMask;
+
+ switch (pname) {
+ case GL_FOG_MODE:
+ switch (param) {
+ case GL_EXP:
+ gCCPriv->GeometryMode |= GM_FogExp;
+ break;
+ case GL_EXP2:
+ gCCPriv->GeometryMode |= GM_FogExpSquared;
+ break;
+ case GL_LINEAR:
+ gCCPriv->GeometryMode |= GM_FogLinear;
+ break;
+ }
+ break;
+ }
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, GeometryMode, gCCPriv->GeometryMode);
}
void _gamma_Fogiv(GLenum pname, const GLint *params)
@@ -1378,6 +1608,16 @@ void _gamma_Fogiv(GLenum pname, const GLint *params)
void _gamma_FrontFace(GLenum mode)
{
DEBUG_GLCMDS(("FrontFace: %04x\n", (int)mode));
+
+ gCCPriv->GeometryMode &= ~GM_FFMask;
+
+ if (mode == GL_CCW)
+ gCCPriv->GeometryMode |= GM_FrontFaceCCW;
+ else
+ gCCPriv->GeometryMode |= GM_FrontFaceCW;
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, GeometryMode, gCCPriv->GeometryMode);
}
void _gamma_Frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
@@ -1463,14 +1703,24 @@ void _gamma_GetFloatv(GLenum val, GLfloat *f)
void _gamma_GetIntegerv(GLenum val, GLint *i)
{
DEBUG_GLCMDS(("GetIntegerv: %04x\n", (int)val));
+
+ switch (val) {
+ case GL_MAX_TEXTURE_SIZE:
+ *i = 2048;
+ break;
+ }
}
void _gamma_GetLightfv(GLenum light, GLenum pname, GLfloat *params)
{
+ DEBUG_GLCMDS(("GetLightfv: %04x %04x %f\n",
+ (int)light, (int)pname, *params));
}
void _gamma_GetLightiv(GLenum light, GLenum pname, GLint *params)
{
+ DEBUG_GLCMDS(("GetLightiv: %04x %04x %d\n",
+ (int)light, (int)pname, *params));
}
void _gamma_GetMapdv(GLenum target, GLenum query, GLdouble *v)
@@ -1654,6 +1904,12 @@ GLboolean _gamma_IsEnabled(GLenum cap)
{
DEBUG_GLCMDS(("IsEnabled: %04x\n", (int)cap));
+ switch (cap) {
+ case GL_LIGHTING:
+ return ((gCCPriv->LightingMode & LightingModeEnable)?GL_TRUE:GL_FALSE);
+ break;
+ }
+
return GL_TRUE;
}
@@ -1673,10 +1929,44 @@ GLboolean _gamma_IsTexture(GLuint texture)
void _gamma_LightModelf(GLenum pname, GLfloat param)
{
+ DEBUG_GLCMDS(("LightModelf: %04x %f\n",
+ (int)pname, param));
}
void _gamma_LightModelfv(GLenum pname, const GLfloat *params)
{
+ DEBUG_GLCMDS(("LightModelfv: %04x %f\n",
+ (int)pname, *params));
+
+ switch (pname) {
+ case GL_LIGHT_MODEL_AMBIENT:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ /* We don't do alpha */
+ WRITEF(gCCPriv->buf, SceneAmbientColorBlue, params[2]);
+ WRITEF(gCCPriv->buf, SceneAmbientColorGreen, params[1]);
+ WRITEF(gCCPriv->buf, SceneAmbientColorRed, params[0]);
+ break;
+ case GL_LIGHT_MODEL_LOCAL_VIEWER:
+ if ((int)params[0] != 0)
+ gCCPriv->LightingMode |= LightingModeLocalViewer;
+ else
+ gCCPriv->LightingMode &= ~LightingModeLocalViewer;
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, LightingMode, gCCPriv->LightingMode);
+ break;
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ if ((int)params[0] != 0) {
+ gCCPriv->LightingMode |= LightingModeTwoSides;
+ gCCPriv->MaterialMode |= MaterialModeTwoSides;
+ } else {
+ gCCPriv->LightingMode &= ~LightingModeTwoSides;
+ gCCPriv->MaterialMode &= ~MaterialModeTwoSides;
+ }
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
+ WRITE(gCCPriv->buf, LightingMode, gCCPriv->LightingMode);
+ WRITE(gCCPriv->buf, MaterialMode, gCCPriv->MaterialMode);
+ break;
+ }
}
void _gamma_LightModeli(GLenum pname, GLint param)
@@ -1689,10 +1979,173 @@ void _gamma_LightModeliv(GLenum pname, const GLint *params)
void _gamma_Lightf(GLenum light, GLenum pname, GLfloat param)
{
+ DEBUG_GLCMDS(("Lightf: %04x %04x %f\n",
+ (int)light, (int)pname, param));
}
void _gamma_Lightfv(GLenum light, GLenum pname, const GLfloat *params)
{
+ GLfloat l,x,y,z;
+ DEBUG_GLCMDS(("Lightfv: %04x %04x %f\n",
+ (int)light, (int)pname, *params));
+
+ switch(light) {
+ case GL_LIGHT0:
+ switch (pname) {
+ case GL_AMBIENT:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ /* We don't do alpha */
+ WRITEF(gCCPriv->buf, Light0AmbientIntensityBlue, params[2]);
+ WRITEF(gCCPriv->buf, Light0AmbientIntensityGreen, params[1]);
+ WRITEF(gCCPriv->buf, Light0AmbientIntensityRed, params[0]);
+ break;
+ case GL_DIFFUSE:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ /* We don't do alpha */
+ WRITEF(gCCPriv->buf, Light0DiffuseIntensityBlue, params[2]);
+ WRITEF(gCCPriv->buf, Light0DiffuseIntensityGreen, params[1]);
+ WRITEF(gCCPriv->buf, Light0DiffuseIntensityRed, params[0]);
+ break;
+ case GL_SPECULAR:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ /* We don't do alpha */
+ WRITEF(gCCPriv->buf, Light0SpecularIntensityBlue, params[2]);
+ WRITEF(gCCPriv->buf, Light0SpecularIntensityGreen, params[1]);
+ WRITEF(gCCPriv->buf, Light0SpecularIntensityRed, params[0]);
+ break;
+ case GL_POSITION:
+ /* Normalize <x,y,z> */
+ x = params[0]; y = params[1]; z = params[2];
+ l = sqrt(x*x + y*y + z*z);
+ x /= l;
+ y /= l;
+ z /= l;
+ if ((int)params[3] != 0) {
+ gCCPriv->Light0Mode |= Light0ModeAttenuation;
+ gCCPriv->Light0Mode |= Light0ModeLocal;
+ } else {
+ gCCPriv->Light0Mode &= ~Light0ModeAttenuation;
+ gCCPriv->Light0Mode &= ~Light0ModeLocal;
+ }
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 5);
+ WRITE(gCCPriv->buf, Light0Mode, gCCPriv->Light0Mode);
+ WRITEF(gCCPriv->buf, Light0PositionW, params[3]);
+ WRITEF(gCCPriv->buf, Light0PositionZ, z);
+ WRITEF(gCCPriv->buf, Light0PositionY, y);
+ WRITEF(gCCPriv->buf, Light0PositionX, x);
+ break;
+ case GL_SPOT_DIRECTION:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ WRITEF(gCCPriv->buf, Light0SpotlightDirectionZ, params[3]);
+ WRITEF(gCCPriv->buf, Light0SpotlightDirectionY, params[2]);
+ WRITEF(gCCPriv->buf, Light0SpotlightDirectionX, params[1]);
+ /* WRITEF(gCCPriv->buf, Light0SpotlightDirectionW, params[0]); */
+ break;
+ case GL_SPOT_EXPONENT:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITEF(gCCPriv->buf, Light0SpotlightExponent, params[0]);
+ break;
+ case GL_SPOT_CUTOFF:
+ if ((int)params[0] != -1)
+ gCCPriv->Light0Mode |= Light0ModeSpotLight;
+ else
+ gCCPriv->Light0Mode &= ~Light0ModeSpotLight;
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
+ WRITE(gCCPriv->buf, Light0Mode, gCCPriv->Light0Mode);
+ WRITEF(gCCPriv->buf, Light0CosSpotlightCutoffAngle, params[0]);
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITEF(gCCPriv->buf, Light0ConstantAttenuation, params[0]);
+ break;
+ case GL_LINEAR_ATTENUATION:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITEF(gCCPriv->buf, Light0LinearAttenuation, params[0]);
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITEF(gCCPriv->buf, Light0QuadraticAttenuation, params[0]);
+ break;
+ }
+ break;
+ case GL_LIGHT1:
+ switch (pname) {
+ case GL_AMBIENT:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ /* We don't do alpha */
+ WRITEF(gCCPriv->buf, Light1AmbientIntensityBlue, params[2]);
+ WRITEF(gCCPriv->buf, Light1AmbientIntensityGreen, params[1]);
+ WRITEF(gCCPriv->buf, Light1AmbientIntensityRed, params[0]);
+ break;
+ case GL_DIFFUSE:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ /* We don't do alpha */
+ WRITEF(gCCPriv->buf, Light1DiffuseIntensityBlue, params[2]);
+ WRITEF(gCCPriv->buf, Light1DiffuseIntensityGreen, params[1]);
+ WRITEF(gCCPriv->buf, Light1DiffuseIntensityRed, params[0]);
+ break;
+ case GL_SPECULAR:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ /* We don't do alpha */
+ WRITEF(gCCPriv->buf, Light1SpecularIntensityBlue, params[2]);
+ WRITEF(gCCPriv->buf, Light1SpecularIntensityGreen, params[1]);
+ WRITEF(gCCPriv->buf, Light1SpecularIntensityRed, params[0]);
+ break;
+ case GL_POSITION:
+ /* Normalize <x,y,z> */
+ x = params[0]; y = params[1]; z = params[2];
+ l = sqrt(x*x + y*y + z*z);
+ x /= l;
+ y /= l;
+ z /= l;
+ if ((int)params[3] != 0) {
+ gCCPriv->Light1Mode |= Light1ModeAttenuation;
+ gCCPriv->Light1Mode |= Light1ModeLocal;
+ } else {
+ gCCPriv->Light0Mode &= ~Light0ModeAttenuation;
+ gCCPriv->Light0Mode &= ~Light0ModeLocal;
+ }
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 5);
+ WRITE(gCCPriv->buf, Light1Mode, gCCPriv->Light1Mode);
+ WRITEF(gCCPriv->buf, Light1PositionW, params[3]);
+ WRITEF(gCCPriv->buf, Light1PositionZ, z);
+ WRITEF(gCCPriv->buf, Light1PositionY, y);
+ WRITEF(gCCPriv->buf, Light1PositionX, x);
+ break;
+ case GL_SPOT_DIRECTION:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ WRITEF(gCCPriv->buf, Light1SpotlightDirectionZ, params[3]);
+ WRITEF(gCCPriv->buf, Light1SpotlightDirectionY, params[2]);
+ WRITEF(gCCPriv->buf, Light1SpotlightDirectionX, params[1]);
+ /* WRITEF(gCCPriv->buf, Light1SpotlightDirectionW, params[0]); */
+ break;
+ case GL_SPOT_EXPONENT:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITEF(gCCPriv->buf, Light1SpotlightExponent, params[0]);
+ break;
+ case GL_SPOT_CUTOFF:
+ if ((int)params[0] != -1)
+ gCCPriv->Light1Mode |= Light1ModeSpotLight;
+ else
+ gCCPriv->Light1Mode &= ~Light1ModeSpotLight;
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
+ WRITE(gCCPriv->buf, Light1Mode, gCCPriv->Light1Mode);
+ WRITEF(gCCPriv->buf, Light1CosSpotlightCutoffAngle, params[0]);
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITEF(gCCPriv->buf, Light1ConstantAttenuation, params[0]);
+ break;
+ case GL_LINEAR_ATTENUATION:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITEF(gCCPriv->buf, Light1LinearAttenuation, params[0]);
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITEF(gCCPriv->buf, Light1QuadraticAttenuation, params[0]);
+ break;
+ }
+ }
}
void _gamma_Lighti(GLenum light, GLenum pname, GLint param)
@@ -1817,6 +2270,104 @@ void _gamma_Materialfv(GLenum face, GLenum pname, const GLfloat *params)
{
DEBUG_GLCMDS(("Materialfv: %04x %04x %f\n",
(int)face, (int)pname, *params));
+
+ gCCPriv->MaterialMode |= MaterialModeEnable;
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, MaterialMode, gCCPriv->MaterialMode);
+
+ if ((face == GL_FRONT) || (face == GL_FRONT_AND_BACK)) {
+ switch (pname) {
+ case GL_AMBIENT:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ WRITEF(gCCPriv->buf, FrontAmbientColorBlue, params[2]);
+ WRITEF(gCCPriv->buf, FrontAmbientColorGreen, params[1]);
+ WRITEF(gCCPriv->buf, FrontAmbientColorRed, params[0]);
+ break;
+ case GL_DIFFUSE:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 4);
+ WRITEF(gCCPriv->buf, FrontAlpha, params[3]);
+ WRITEF(gCCPriv->buf, FrontDiffuseColorBlue, params[2]);
+ WRITEF(gCCPriv->buf, FrontDiffuseColorGreen, params[1]);
+ WRITEF(gCCPriv->buf, FrontDiffuseColorRed, params[0]);
+ break;
+ case GL_SPECULAR:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ WRITEF(gCCPriv->buf, FrontSpecularColorBlue, params[2]);
+ WRITEF(gCCPriv->buf, FrontSpecularColorGreen, params[1]);
+ WRITEF(gCCPriv->buf, FrontSpecularColorRed, params[0]);
+ break;
+ case GL_EMISSION:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ WRITEF(gCCPriv->buf, FrontEmissiveColorBlue, params[2]);
+ WRITEF(gCCPriv->buf, FrontEmissiveColorGreen, params[1]);
+ WRITEF(gCCPriv->buf, FrontEmissiveColorRed, params[0]);
+ break;
+ case GL_SHININESS:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITEF(gCCPriv->buf, FrontSpecularExponent, params[0]);
+ break;
+ case GL_AMBIENT_AND_DIFFUSE:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 7);
+ WRITEF(gCCPriv->buf, FrontAmbientColorBlue, params[2]);
+ WRITEF(gCCPriv->buf, FrontAmbientColorGreen, params[1]);
+ WRITEF(gCCPriv->buf, FrontAmbientColorRed, params[0]);
+ WRITEF(gCCPriv->buf, FrontAlpha, params[3]);
+ WRITEF(gCCPriv->buf, FrontDiffuseColorBlue, params[2]);
+ WRITEF(gCCPriv->buf, FrontDiffuseColorGreen, params[1]);
+ WRITEF(gCCPriv->buf, FrontDiffuseColorRed, params[0]);
+ break;
+ case GL_COLOR_INDEXES:
+ /* NOT_DONE */
+ break;
+ }
+ }
+
+ if ((face == GL_BACK) || (face == GL_FRONT_AND_BACK)) {
+ switch (pname) {
+ case GL_AMBIENT:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ WRITEF(gCCPriv->buf, BackAmbientColorBlue, params[2]);
+ WRITEF(gCCPriv->buf, BackAmbientColorGreen, params[1]);
+ WRITEF(gCCPriv->buf, BackAmbientColorRed, params[0]);
+ break;
+ case GL_DIFFUSE:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 4);
+ WRITEF(gCCPriv->buf, BackAlpha, params[3]);
+ WRITEF(gCCPriv->buf, BackDiffuseColorBlue, params[2]);
+ WRITEF(gCCPriv->buf, BackDiffuseColorGreen, params[1]);
+ WRITEF(gCCPriv->buf, BackDiffuseColorRed, params[0]);
+ break;
+ case GL_SPECULAR:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ WRITEF(gCCPriv->buf, BackSpecularColorBlue, params[2]);
+ WRITEF(gCCPriv->buf, BackSpecularColorGreen, params[1]);
+ WRITEF(gCCPriv->buf, BackSpecularColorRed, params[0]);
+ break;
+ case GL_EMISSION:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ WRITEF(gCCPriv->buf, BackEmissiveColorBlue, params[2]);
+ WRITEF(gCCPriv->buf, BackEmissiveColorGreen, params[1]);
+ WRITEF(gCCPriv->buf, BackEmissiveColorRed, params[0]);
+ break;
+ case GL_SHININESS:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITEF(gCCPriv->buf, BackSpecularExponent, params[0]);
+ break;
+ case GL_AMBIENT_AND_DIFFUSE:
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 7);
+ WRITEF(gCCPriv->buf, BackAmbientColorBlue, params[2]);
+ WRITEF(gCCPriv->buf, BackAmbientColorGreen, params[1]);
+ WRITEF(gCCPriv->buf, BackAmbientColorRed, params[0]);
+ WRITEF(gCCPriv->buf, BackAlpha, params[3]);
+ WRITEF(gCCPriv->buf, BackDiffuseColorBlue, params[2]);
+ WRITEF(gCCPriv->buf, BackDiffuseColorGreen, params[1]);
+ WRITEF(gCCPriv->buf, BackDiffuseColorRed, params[0]);
+ break;
+ case GL_COLOR_INDEXES:
+ /* NOT_DONE */
+ break;
+ }
+ }
}
void _gamma_Materiali(GLenum face, GLenum pname, GLint param)
@@ -1837,9 +2388,9 @@ void _gamma_MatrixMode(GLenum mode)
switch (mode) {
case GL_TEXTURE:
- /* Eanble the Texture transform */
+ /* Enable the Texture transform */
CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
- WRITE(gCCPriv->buf, TransformModeOr, 0x00000010);
+ WRITE(gCCPriv->buf, TransformModeOr, XM_XformTexture);
case GL_MODELVIEW:
case GL_PROJECTION:
gCCPriv->MatrixMode = mode;
@@ -1878,52 +2429,114 @@ void _gamma_NewList(GLuint list, GLenum mode)
void _gamma_Normal3b(GLbyte nx, GLbyte ny, GLbyte nz)
{
+ GLfloat x,y,z;
+
DEBUG_GLCMDS(("Normal3b: %d %d %d\n", nx, ny, nz));
+
+ x = BYTE_TO_FLOAT(nx);
+ y = BYTE_TO_FLOAT(ny);
+ z = BYTE_TO_FLOAT(nz);
+
+ _gamma_Normal3f(x,y,z);
}
void _gamma_Normal3bv(const GLbyte *v)
{
+ GLfloat p[3];
+
DEBUG_GLCMDS(("Normal3bv: %d %d %d\n", v[0], v[1], v[2]));
+
+ p[0] = BYTE_TO_FLOAT(v[0]);
+ p[1] = BYTE_TO_FLOAT(v[1]);
+ p[2] = BYTE_TO_FLOAT(v[2]);
+
+ _gamma_Normal3fv(p);
}
void _gamma_Normal3d(GLdouble nx, GLdouble ny, GLdouble nz)
{
DEBUG_GLCMDS(("Normal3d: %f %f %f\n", nx, ny, nz));
+
+ _gamma_Normal3f((GLfloat)nx,(GLfloat)ny,(GLfloat)nz);
}
void _gamma_Normal3dv(const GLdouble *v)
{
DEBUG_GLCMDS(("Normal3dv: %f %f %f\n", v[0], v[1], v[2]));
+
+ _gamma_Normal3fv((GLfloat*)v);
}
void _gamma_Normal3f(GLfloat nx, GLfloat ny, GLfloat nz)
{
DEBUG_GLCMDS(("Normal3f: %f %f %f\n", nx, ny, nz));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ WRITEF(gCCPriv->buf, Nz, nz);
+ WRITEF(gCCPriv->buf, Ny, ny);
+ WRITEF(gCCPriv->buf, Nx, nx);
}
void _gamma_Normal3fv(const GLfloat *v)
{
DEBUG_GLCMDS(("Normal3fv: %f %f %f\n", v[0], v[1], v[2]));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ WRITEF(gCCPriv->buf, Nz, v[2]);
+ WRITEF(gCCPriv->buf, Ny, v[1]);
+ WRITEF(gCCPriv->buf, Nx, v[0]);
}
void _gamma_Normal3i(GLint nx, GLint ny, GLint nz)
{
+ GLfloat x,y,z;
+
DEBUG_GLCMDS(("Normal3i: %d %d %d\n", (int)nx, (int)ny, (int)nz));
+
+ x = INT_TO_FLOAT(nx);
+ y = INT_TO_FLOAT(ny);
+ z = INT_TO_FLOAT(nz);
+
+ _gamma_Normal3f(x,y,z);
}
void _gamma_Normal3iv(const GLint *v)
{
+ GLfloat p[3];
+
DEBUG_GLCMDS(("Normal3iv: %d %d %d\n", (int)v[0], (int)v[1], (int)v[2]));
+
+ p[0] = INT_TO_FLOAT(v[0]);
+ p[1] = INT_TO_FLOAT(v[1]);
+ p[2] = INT_TO_FLOAT(v[2]);
+
+ _gamma_Normal3fv(p);
}
void _gamma_Normal3s(GLshort nx, GLshort ny, GLshort nz)
{
+ GLfloat x,y,z;
+
DEBUG_GLCMDS(("Normal3s: %d %d %d\n", nx, ny, nz));
+
+ x = SHORT_TO_FLOAT(nx);
+ y = SHORT_TO_FLOAT(ny);
+ z = SHORT_TO_FLOAT(nz);
+
+ _gamma_Normal3f(x,y,z);
}
void _gamma_Normal3sv(const GLshort *v)
{
+ GLfloat p[3];
+
DEBUG_GLCMDS(("Normal3sv: %d %d %d\n", v[0], v[1], v[2]));
+
+ p[0] = SHORT_TO_FLOAT(v[0]);
+ p[1] = SHORT_TO_FLOAT(v[1]);
+ p[2] = SHORT_TO_FLOAT(v[2]);
+
+ _gamma_Normal3fv(p);
}
void _gamma_NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
@@ -2020,6 +2633,56 @@ void _gamma_PointSize(GLfloat size)
void _gamma_PolygonMode(GLenum face, GLenum mode)
{
DEBUG_GLCMDS(("PolygonMode: %04x %04x\n", (int)face, (int)mode));
+
+ gCCPriv->GeometryMode &= ~GM_FB_PolyMask;
+
+ switch (mode) {
+ case GL_FILL:
+ switch (face) {
+ case GL_FRONT:
+ gCCPriv->GeometryMode |= GM_FrontPolyFill;
+ break;
+ case GL_BACK:
+ gCCPriv->GeometryMode |= GM_BackPolyFill;
+ break;
+ case GL_FRONT_AND_BACK:
+ gCCPriv->GeometryMode |= GM_FrontPolyFill;
+ gCCPriv->GeometryMode |= GM_BackPolyFill;
+ break;
+ }
+ break;
+ case GL_LINE:
+ switch (face) {
+ case GL_FRONT:
+ gCCPriv->GeometryMode |= GM_FrontPolyLine;
+ break;
+ case GL_BACK:
+ gCCPriv->GeometryMode |= GM_BackPolyLine;
+ break;
+ case GL_FRONT_AND_BACK:
+ gCCPriv->GeometryMode |= GM_FrontPolyLine;
+ gCCPriv->GeometryMode |= GM_BackPolyLine;
+ break;
+ }
+ break;
+ case GL_POINT:
+ switch (face) {
+ case GL_FRONT:
+ gCCPriv->GeometryMode |= GM_FrontPolyPoint;
+ break;
+ case GL_BACK:
+ gCCPriv->GeometryMode |= GM_BackPolyPoint;
+ break;
+ case GL_FRONT_AND_BACK:
+ gCCPriv->GeometryMode |= GM_FrontPolyPoint;
+ gCCPriv->GeometryMode |= GM_BackPolyPoint;
+ break;
+ }
+ break;
+ }
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, GeometryMode, gCCPriv->GeometryMode);
}
void _gamma_PolygonOffset(GLfloat factor, GLfloat units)
@@ -2272,6 +2935,13 @@ void _gamma_Rectdv(const GLdouble *v1, const GLdouble *v2)
void _gamma_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
{
DEBUG_GLCMDS(("Rectf: %f %f %f %f\n", x1, y1, x2, y2));
+
+ _gamma_Begin(GL_POLYGON);
+ _gamma_Vertex2f(x1,y1);
+ _gamma_Vertex2f(x2,y1);
+ _gamma_Vertex2f(x2,y2);
+ _gamma_Vertex2f(x1,y2);
+ _gamma_End();
}
void _gamma_Rectfv(const GLfloat *v1, const GLfloat *v2)
@@ -2678,6 +3348,33 @@ void _gamma_TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
{
DEBUG_GLCMDS(("TexEnvfv: %04x %04x %f\n",
(int)target, (int)pname, *params));
+
+ if (target != GL_TEXTURE_ENV) {
+ /* ERROR !! */
+ }
+
+ switch (pname) {
+ case GL_TEXTURE_ENV_MODE:
+ gCCPriv->curTexObj->TextureColorMode &= ~TCM_ApplicationMask;
+ switch ((int)params[0]) {
+ case GL_MODULATE:
+ gCCPriv->curTexObj->TextureColorMode |= TCM_Modulate;
+ break;
+ case GL_DECAL:
+ gCCPriv->curTexObj->TextureColorMode |= TCM_Decal;
+ break;
+ case GL_BLEND:
+ gCCPriv->curTexObj->TextureColorMode |= TCM_Blend;
+ break;
+ case GL_REPLACE:
+ gCCPriv->curTexObj->TextureColorMode |= TCM_Replace;
+ break;
+ }
+ }
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, TextureColorMode,
+ gCCPriv->curTexObj->TextureColorMode);
}
void _gamma_TexEnvi(GLenum target, GLenum pname, GLint param)
@@ -2745,10 +3442,12 @@ void _gamma_TexImage2D(GLenum target, GLint level, GLint components, GLsizei wid
if (target == GL_TEXTURE_1D) {
/* NOT_DONE */
+ DEBUG_ERROR(("TexImage2D: 1D requested - ERROR\n"));
} else if (target == GL_TEXTURE_2D) {
/* NOT_DONE: The follow are not currently supported... */
- if (border != 0 || format != GL_RGBA || type != GL_UNSIGNED_BYTE ||
+ if (border != 0 /* || format != GL_RGBA */ || type != GL_UNSIGNED_BYTE ||
(components != 3 && components != 4)) {
+ DEBUG_ERROR(("TexImage2D: 2D op not supported - ERROR\n"));
return;
}
@@ -2790,7 +3489,11 @@ void _gamma_TexImage2D(GLenum target, GLint level, GLint components, GLsizei wid
break;
}
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
t->TextureFormat = (TF_LittleEndian |
+#else
+ t->TextureFormat = (TF_BigEndian |
+#endif
TF_ColorOrder_BGR |
TF_Compnents_4 |
TF_OutputFmt_Texel);
@@ -2804,14 +3507,17 @@ void _gamma_TexImage2D(GLenum target, GLint level, GLint components, GLsizei wid
t->image[level] = driTMMInsertImage(gCCPriv->tmm,
width, height, 1<<l2d,
image, NULL);
+
if (!t->image[level]) {
/* NOT_DONE: Handle error */
+ DEBUG_ERROR(("TexImage2D: unable1\n"));
}
/* Make the new image resident (and all of the other mipmaps) */
- if (!driTMMMakeImagesResident(gCCPriv->tmm, MIPMAP_LEVELS,
- t->image, addrs)) {
+ if (driTMMMakeImagesResident(gCCPriv->tmm, MIPMAP_LEVELS,
+ t->image, addrs) < 0) {
/* NOT_DONE: Handle error */
+ DEBUG_ERROR(("TexImage2D: unable2\n"));
}
for (i = 0; i < MIPMAP_LEVELS; i++)
@@ -3010,6 +3716,123 @@ void _gamma_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
{
DEBUG_GLCMDS(("TexParameterfv: %04x %04x %f\n",
(int)target, (int)pname, *params));
+
+ if (target == GL_TEXTURE_1D) {
+ /* NOT_DONE */
+ } else if (target == GL_TEXTURE_2D) {
+ switch (pname) {
+ case GL_TEXTURE_MAG_FILTER:
+ gCCPriv->curTexObj2D->TextureReadMode &= ~TRM_Mag_Mask;
+ switch ((int)params[0]) {
+ case GL_NEAREST:
+ gCCPriv->curTexObj2D->TextureReadMode |=
+ TRM_Mag_Nearest;
+ break;
+ case GL_LINEAR:
+ gCCPriv->curTexObj2D->TextureReadMode |=
+ TRM_Mag_Linear;
+ break;
+ default:
+ break;
+ }
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
+ WRITE(gCCPriv->buf, TextureReadMode,
+ gCCPriv->curTexObj2D->TextureReadMode);
+ break;
+ case GL_TEXTURE_MIN_FILTER:
+ gCCPriv->curTexObj2D->TextureReadMode &= ~TRM_Min_Mask;
+ gCCPriv->curTexObj2D->TextureReadMode |= TRM_MipMapEnable;
+ gCCPriv->curTexObj2D->TextureAddressMode |= TAM_LODEnable;
+ switch ((int)params[0]) {
+ case GL_NEAREST:
+ gCCPriv->curTexObj2D->TextureReadMode |=
+ TRM_Min_Nearest;
+ gCCPriv->curTexObj2D->TextureReadMode &= ~TRM_MipMapEnable;
+ gCCPriv->curTexObj2D->TextureAddressMode &= ~TAM_LODEnable;
+ break;
+ case GL_LINEAR:
+ gCCPriv->curTexObj2D->TextureReadMode |=
+ TRM_Min_Linear;
+ gCCPriv->curTexObj2D->TextureReadMode &= ~TRM_MipMapEnable;
+ gCCPriv->curTexObj2D->TextureAddressMode &= ~TAM_LODEnable;
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ gCCPriv->curTexObj2D->TextureReadMode |=
+ TRM_Min_NearestMMNearest;
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ gCCPriv->curTexObj2D->TextureReadMode |=
+ TRM_Min_NearestMMLinear;
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ gCCPriv->curTexObj2D->TextureReadMode |=
+ TRM_Min_LinearMMNearest;
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ gCCPriv->curTexObj2D->TextureReadMode |=
+ TRM_Min_LinearMMLinear;
+ break;
+ default:
+ break;
+ }
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
+ WRITE(gCCPriv->buf, TextureReadMode,
+ gCCPriv->curTexObj2D->TextureReadMode);
+ WRITE(gCCPriv->buf, TextureAddressMode,
+ gCCPriv->curTexObj2D->TextureAddressMode);
+ break;
+ case GL_TEXTURE_WRAP_S:
+ gCCPriv->curTexObj2D->TextureAddressMode &= ~TAM_SWrap_Mask;
+ gCCPriv->curTexObj2D->TextureReadMode &= ~TRM_UWrap_Mask;
+ switch ((int)params[0]) {
+ case GL_CLAMP:
+ gCCPriv->curTexObj2D->TextureAddressMode |= TAM_SWrap_Clamp;
+ gCCPriv->curTexObj2D->TextureReadMode |= TRM_UWrap_Clamp;
+ break;
+ case GL_REPEAT:
+ gCCPriv->curTexObj2D->TextureAddressMode |= TAM_SWrap_Repeat;
+ gCCPriv->curTexObj2D->TextureReadMode |= TRM_UWrap_Repeat;
+ break;
+ default:
+ break;
+ }
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
+ WRITE(gCCPriv->buf, TextureReadMode,
+ gCCPriv->curTexObj2D->TextureReadMode);
+ WRITE(gCCPriv->buf, TextureAddressMode,
+ gCCPriv->curTexObj2D->TextureAddressMode);
+ break;
+ case GL_TEXTURE_WRAP_T:
+ gCCPriv->curTexObj2D->TextureAddressMode &= ~TAM_TWrap_Mask;
+ gCCPriv->curTexObj2D->TextureReadMode &= ~TRM_VWrap_Mask;
+ switch ((int)params[0]) {
+ case GL_CLAMP:
+ gCCPriv->curTexObj2D->TextureAddressMode |= TAM_TWrap_Clamp;
+ gCCPriv->curTexObj2D->TextureReadMode |= TRM_VWrap_Clamp;
+ break;
+ case GL_REPEAT:
+ gCCPriv->curTexObj2D->TextureAddressMode |= TAM_TWrap_Repeat;
+ gCCPriv->curTexObj2D->TextureReadMode |= TRM_VWrap_Repeat;
+ break;
+ default:
+ break;
+ }
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
+ WRITE(gCCPriv->buf, TextureReadMode,
+ gCCPriv->curTexObj2D->TextureReadMode);
+ WRITE(gCCPriv->buf, TextureAddressMode,
+ gCCPriv->curTexObj2D->TextureAddressMode);
+ break;
+ default:
+ break;
+ }
+ } else {
+ /* ERROR !! */
+ }
}
void _gamma_TexParameteri(GLenum target, GLenum pname, GLint param)
@@ -3054,8 +3877,8 @@ void _gamma_TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffs
** format for the image that it is replacing.
*/
- if (!driTMMSubImage(gCCPriv->tmm, gCCPriv->curTexObj2D->image[level],
- xoffset, yoffset, width, height, image)) {
+ if (driTMMSubImage(gCCPriv->tmm, gCCPriv->curTexObj2D->image[level],
+ xoffset, yoffset, width, height, image) < 0) {
/* NOT_DONE: Handle error */
}
} else {
@@ -3089,7 +3912,7 @@ void _gamma_Translatef(GLfloat x, GLfloat y, GLfloat z)
GLfloat m[16];
int i;
- DEBUG_GLCMDS(("Tranlatef: %f %f %f\n", x, y, z));
+ DEBUG_GLCMDS(("Translatef: %f %f %f\n", x, y, z));
for (i = 0; i < 16; i++)
if (i % 5 == 0)
@@ -3108,26 +3931,25 @@ void _gamma_Translatef(GLfloat x, GLfloat y, GLfloat z)
void _gamma_Vertex2d(GLdouble x, GLdouble y)
{
DEBUG_GLCMDS(("Vertex2d: %f %f\n", x, y));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)y);
+ WRITEF(gCCPriv->buf, Vx2, (GLfloat)x);
}
void _gamma_Vertex2dv(const GLdouble *v)
{
DEBUG_GLCMDS(("Vertex2dv: %f %f\n", v[0], v[1]));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)v[1]);
+ WRITEF(gCCPriv->buf, Vx2, (GLfloat)v[0]);
}
void _gamma_Vertex2f(GLfloat x, GLfloat y)
{
DEBUG_GLCMDS(("Vertex2f: %f %f\n", x, y));
-#ifdef RANDOMIZE_COLORS
- {
- GLuint c;
- c = (random() / (double)RAND_MAX) * 16777216;
- CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
- WRITE(gCCPriv->buf, PackedColor4, c);
- }
-#endif
-
CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
WRITEF(gCCPriv->buf, Vy, y);
WRITEF(gCCPriv->buf, Vx2, x);
@@ -3136,51 +3958,72 @@ void _gamma_Vertex2f(GLfloat x, GLfloat y)
void _gamma_Vertex2fv(const GLfloat *v)
{
DEBUG_GLCMDS(("Vertex2fv: %f %f\n", v[0], v[1]));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
+ WRITEF(gCCPriv->buf, Vy, v[1]);
+ WRITEF(gCCPriv->buf, Vx2, v[0]);
}
void _gamma_Vertex2i(GLint x, GLint y)
{
DEBUG_GLCMDS(("Vertex2i: %d %d\n", (int)x, (int)y));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)y);
+ WRITEF(gCCPriv->buf, Vx2, (GLfloat)x);
}
void _gamma_Vertex2iv(const GLint *v)
{
DEBUG_GLCMDS(("Vertex2iv: %d %d\n", (int)v[0], (int)v[1]));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)v[1]);
+ WRITEF(gCCPriv->buf, Vx2, (GLfloat)v[0]);
}
void _gamma_Vertex2s(GLshort x, GLshort y)
{
DEBUG_GLCMDS(("Vertex2s: %d %d\n", x, y));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)y);
+ WRITEF(gCCPriv->buf, Vx2, (GLfloat)x);
}
void _gamma_Vertex2sv(const GLshort *v)
{
DEBUG_GLCMDS(("Vertex2sv: %d %d\n", v[0], v[1]));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 2);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)v[1]);
+ WRITEF(gCCPriv->buf, Vx2, (GLfloat)v[0]);
}
void _gamma_Vertex3d(GLdouble x, GLdouble y, GLdouble z)
{
DEBUG_GLCMDS(("Vertex3d: %f %f %f\n", x, y, z));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ WRITEF(gCCPriv->buf, Vz, (GLfloat)z);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)y);
+ WRITEF(gCCPriv->buf, Vx3, (GLfloat)x);
}
void _gamma_Vertex3dv(const GLdouble *v)
{
DEBUG_GLCMDS(("Vertex2fv: %f %f %f\n", v[0], v[1], v[2]));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ WRITEF(gCCPriv->buf, Vz, (GLfloat)v[2]);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)v[1]);
+ WRITEF(gCCPriv->buf, Vx3, (GLfloat)v[0]);
}
void _gamma_Vertex3f(GLfloat x, GLfloat y, GLfloat z)
{
DEBUG_GLCMDS(("Vertex3f: %f %f %f\n", x, y, z));
-#ifdef RANDOMIZE_COLORS
- {
- GLuint c;
- c = (random() / (double)RAND_MAX) * 16777216;
- CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
- WRITE(gCCPriv->buf, PackedColor4, c);
- }
-#endif
-
CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
WRITEF(gCCPriv->buf, Vz, z);
WRITEF(gCCPriv->buf, Vy, y);
@@ -3191,15 +4034,6 @@ void _gamma_Vertex3fv(const GLfloat *v)
{
DEBUG_GLCMDS(("Vertex3fv: %f %f %f\n", v[0], v[1], v[2]));
-#ifdef RANDOMIZE_COLORS
- {
- GLuint c;
- c = (random() / (double)RAND_MAX) * 16777216;
- CHECK_DMA_BUFFER(gCC, gCCPriv, 1);
- WRITE(gCCPriv->buf, PackedColor4, c);
- }
-#endif
-
CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
WRITEF(gCCPriv->buf, Vz, v[2]);
WRITEF(gCCPriv->buf, Vy, v[1]);
@@ -3209,62 +4043,130 @@ void _gamma_Vertex3fv(const GLfloat *v)
void _gamma_Vertex3i(GLint x, GLint y, GLint z)
{
DEBUG_GLCMDS(("Vertex3i: %d %d %d\n", (int)x, (int)y, (int)z));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ WRITEF(gCCPriv->buf, Vz, (GLfloat)z);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)y);
+ WRITEF(gCCPriv->buf, Vx3, (GLfloat)x);
}
void _gamma_Vertex3iv(const GLint *v)
{
DEBUG_GLCMDS(("Vertex3iv: %d %d %d\n", (int)v[0], (int)v[1], (int)v[2]));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ WRITEF(gCCPriv->buf, Vz, (GLfloat)v[2]);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)v[1]);
+ WRITEF(gCCPriv->buf, Vx3, (GLfloat)v[0]);
}
void _gamma_Vertex3s(GLshort x, GLshort y, GLshort z)
{
DEBUG_GLCMDS(("Vertex3s: %d %d %d\n", x, y, z));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ WRITEF(gCCPriv->buf, Vz, (GLfloat)z);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)y);
+ WRITEF(gCCPriv->buf, Vx3, (GLfloat)x);
}
void _gamma_Vertex3sv(const GLshort *v)
{
DEBUG_GLCMDS(("Vertex3sv: %d %d %d\n", v[0], v[1], v[2]));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 3);
+ WRITEF(gCCPriv->buf, Vz, (GLfloat)v[2]);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)v[1]);
+ WRITEF(gCCPriv->buf, Vx3, (GLfloat)v[0]);
}
void _gamma_Vertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
DEBUG_GLCMDS(("Vertex4d: %f %f %f %f\n", x, y, z, w));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 4);
+ WRITEF(gCCPriv->buf, Vw, (GLfloat)w);
+ WRITEF(gCCPriv->buf, Vz, (GLfloat)z);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)y);
+ WRITEF(gCCPriv->buf, Vx4,(GLfloat)x);
}
void _gamma_Vertex4dv(const GLdouble *v)
{
DEBUG_GLCMDS(("Vertex4dv: %f %f %f %f\n", v[0], v[1], v[2], v[3]));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 4);
+ WRITEF(gCCPriv->buf, Vw, (GLfloat)v[3]);
+ WRITEF(gCCPriv->buf, Vz, (GLfloat)v[2]);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)v[1]);
+ WRITEF(gCCPriv->buf, Vx4, (GLfloat)v[0]);
}
void _gamma_Vertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
DEBUG_GLCMDS(("Vertex4f: %f %f %f %f\n", x, y, z, w));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 4);
+ WRITEF(gCCPriv->buf, Vw, w);
+ WRITEF(gCCPriv->buf, Vz, z);
+ WRITEF(gCCPriv->buf, Vy, y);
+ WRITEF(gCCPriv->buf, Vx4, x);
}
void _gamma_Vertex4fv(const GLfloat *v)
{
DEBUG_GLCMDS(("Vertex4fv: %f %f %f %f\n", v[0], v[1], v[2], v[3]));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 4);
+ WRITEF(gCCPriv->buf, Vw, v[3]);
+ WRITEF(gCCPriv->buf, Vz, v[2]);
+ WRITEF(gCCPriv->buf, Vy, v[1]);
+ WRITEF(gCCPriv->buf, Vx4, v[0]);
}
void _gamma_Vertex4i(GLint x, GLint y, GLint z, GLint w)
{
DEBUG_GLCMDS(("Vertex4i: %d %d %d %d\n", (int)x, (int)y, (int)z, (int)w));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 4);
+ WRITEF(gCCPriv->buf, Vw, (GLfloat)w);
+ WRITEF(gCCPriv->buf, Vz, (GLfloat)z);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)y);
+ WRITEF(gCCPriv->buf, Vx4, (GLfloat)x);
}
void _gamma_Vertex4iv(const GLint *v)
{
DEBUG_GLCMDS(("Vertex4iv: %d %d %d %d\n",
(int)v[0], (int)v[1], (int)v[2], (int)v[3]));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 4);
+ WRITEF(gCCPriv->buf, Vw, (GLfloat)v[3]);
+ WRITEF(gCCPriv->buf, Vz, (GLfloat)v[2]);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)v[1]);
+ WRITEF(gCCPriv->buf, Vx4, (GLfloat)v[0]);
}
void _gamma_Vertex4s(GLshort x, GLshort y, GLshort z, GLshort w)
{
DEBUG_GLCMDS(("Vertex4s: %d %d %d %d\n", x, y, z, w));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 4);
+ WRITEF(gCCPriv->buf, Vw, (GLfloat)w);
+ WRITEF(gCCPriv->buf, Vz, (GLfloat)z);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)y);
+ WRITEF(gCCPriv->buf, Vx4,(GLfloat)x);
}
void _gamma_Vertex4sv(const GLshort *v)
{
DEBUG_GLCMDS(("Vertex4sv: %d %d %d %d\n", v[0], v[1], v[2], v[3]));
+
+ CHECK_DMA_BUFFER(gCC, gCCPriv, 4);
+ WRITEF(gCCPriv->buf, Vw, (GLfloat)v[3]);
+ WRITEF(gCCPriv->buf, Vz, (GLfloat)v[2]);
+ WRITEF(gCCPriv->buf, Vy, (GLfloat)v[1]);
+ WRITEF(gCCPriv->buf, Vx4, (GLfloat)v[0]);
}
void _gamma_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
@@ -3296,10 +4198,13 @@ void _gamma_Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
oy = y + sy;
CHECK_DMA_BUFFER(gCC, gCCPriv, 4);
- WRITEF(gCCPriv->buf, ViewPortOffsetX, ox);
- WRITEF(gCCPriv->buf, ViewPortOffsetY, oy);
WRITEF(gCCPriv->buf, ViewPortScaleX, sx);
WRITEF(gCCPriv->buf, ViewPortScaleY, sy);
+ WRITEF(gCCPriv->buf, ViewPortOffsetX, ox);
+ WRITEF(gCCPriv->buf, ViewPortOffsetY, oy);
+#if 1 /* Err - this shouldn't be needed, but something isn't flushing */
+ FLUSH_DMA_BUFFER(gCC,gCCPriv);
+#endif
}
diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_init.h b/xc/lib/GL/mesa/src/drv/gamma/gamma_init.h
index ce804d018..e8fd5a0df 100644
--- a/xc/lib/GL/mesa/src/drv/gamma/gamma_init.h
+++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_init.h
@@ -43,7 +43,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "gamma_regs.h"
#include "gamma_macros.h"
#include "gamma_texture.h"
-#include "xmesaP.h"
typedef struct {
int regionCount; /* Count of register regions */
@@ -109,6 +108,12 @@ typedef struct {
int AB_FBReadMode;
int AB_FBReadMode_Save;
int DeltaMode;
+ int ColorMaterialMode;
+ int MaterialMode;
+ int LightingMode;
+ int Light0Mode;
+ int Light1Mode;
+ int ScissorMode;
int Window; /* GID part probably should be in draw priv */
gammaTexObj *curTexObj;
@@ -140,8 +145,8 @@ extern void gammaLoadHWMatrix(void);
extern void gammaInitHW(gammaContextPrivate *gcp);
extern float IdentityMatrix[16];
-extern XMesaContext nullCC;
-extern XMesaContext gCC;
+extern __DRIcontextPrivate *nullCC;
+extern __DRIcontextPrivate *gCC;
extern gammaContextPrivate *gCCPriv;
#endif
diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c
index edb1d3da0..87d68278b 100644
--- a/xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c
+++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c
@@ -29,27 +29,32 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/*
* Authors:
* Kevin E. Martin <kevin@precisioninsight.com>
+ * Alan Hourihane <Alan.Hourihane@btinternet.com>
*
*/
#ifdef GLX_DIRECT_RENDERING
#include "gamma_init.h"
+#include "glint_dri.h"
void gammaInitHW(gammaContextPrivate *gcp)
{
__DRIscreenPrivate *driScrnPriv = gcp->gammaScrnPriv->driScrnPriv;
+ GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)driScrnPriv->pDevPriv;
- /* Set up each MX's ScanLineOwnership for OpenGL */
- CHECK_DMA_BUFFER(nullCC, gcp, 4);
- WRITE(gcp->buf, BroadcastMask, 1);
- WRITE(gcp->buf, ScanLineOwnership, 5); /* Use bottom left as [0,0] */
- WRITE(gcp->buf, BroadcastMask, 2);
- WRITE(gcp->buf, ScanLineOwnership, 1); /* Use bottom left as [0,0] */
+ if (gDRIPriv->numMXDevices == 2) {
+ /* Set up each MX's ScanLineOwnership for OpenGL */
+ CHECK_DMA_BUFFER(nullCC, gcp, 4);
+ WRITE(gcp->buf, BroadcastMask, 1);
+ WRITE(gcp->buf, ScanLineOwnership, 5); /* Use bottom left as [0,0] */
+ WRITE(gcp->buf, BroadcastMask, 2);
+ WRITE(gcp->buf, ScanLineOwnership, 1); /* Use bottom left as [0,0] */
- /* Broadcast to both MX's */
- CHECK_DMA_BUFFER(nullCC, gcp, 1);
- WRITE(gcp->buf, BroadcastMask, 3);
+ /* Broadcast to both MX's */
+ CHECK_DMA_BUFFER(nullCC, gcp, 1);
+ WRITE(gcp->buf, BroadcastMask, 3);
+ }
/* Set MXs to known state */
CHECK_DMA_BUFFER(nullCC, gcp, 27);
@@ -82,6 +87,7 @@ void gammaInitHW(gammaContextPrivate *gcp)
WRITE(gcp->buf, PixelSize, 0);
/* Set Gamma to known state */
+ CHECK_DMA_BUFFER(nullCC, gcp, 10);
WRITE(gcp->buf, TriangleMode, 0);
WRITE(gcp->buf, GeometryMode, 0);
WRITE(gcp->buf, NormalizeMode, 0);
@@ -136,7 +142,10 @@ void gammaInitHW(gammaContextPrivate *gcp)
WRITE(gcp->buf, AlphaTestMode, gcp->AlphaTestMode);
WRITE(gcp->buf, AlphaBlendMode, gcp->AlphaBlendMode);
WRITE(gcp->buf, DitherMode, DitherModeEnable | DM_ColorOrder_RGB);
- WRITE(gcp->buf, RasterizerMode, RM_MultiGLINT | RM_BiasCoordNearHalf);
+ if (gDRIPriv->numMXDevices == 2)
+ WRITE(gcp->buf, RasterizerMode, RM_MultiGLINT | RM_BiasCoordNearHalf);
+ else
+ WRITE(gcp->buf, RasterizerMode, RM_BiasCoordNearHalf);
WRITE(gcp->buf, GLINTWindow, gcp->Window);
WRITE(gcp->buf, FastClearDepth, 0xffffffff);
WRITE(gcp->buf, GLINTDepth, 0xffffffff);
@@ -242,7 +251,7 @@ void gammaInitHW(gammaContextPrivate *gcp)
CHECK_DMA_BUFFER(nullCC, gcp, 5);
WRITE(gcp->buf, GeometryMode, gcp->GeometryMode);
WRITE(gcp->buf, NormalizeMode, NormalizeModeDisable);
- WRITE(gcp->buf, LightingMode, LightingModeDisable);
+ WRITE(gcp->buf, LightingMode, gcp->LightingMode);
WRITE(gcp->buf, ColorMaterialMode, ColorMaterialModeDisable);
WRITE(gcp->buf, MaterialMode, MaterialModeDisable);
@@ -251,18 +260,18 @@ void gammaInitHW(gammaContextPrivate *gcp)
WRITE(gcp->buf, BackSpecularExponent, 0); /* fixed point */
CHECK_DMA_BUFFER(nullCC, gcp, 29);
- WRITEF(gcp->buf, FrontAmbientColorRed, 0.0);
- WRITEF(gcp->buf, FrontAmbientColorGreen, 0.0);
- WRITEF(gcp->buf, FrontAmbientColorBlue, 0.0);
- WRITEF(gcp->buf, BackAmbientColorRed, 0.0);
- WRITEF(gcp->buf, BackAmbientColorGreen, 0.0);
- WRITEF(gcp->buf, BackAmbientColorBlue, 0.0);
- WRITEF(gcp->buf, FrontDiffuseColorRed, 0.0);
- WRITEF(gcp->buf, FrontDiffuseColorGreen, 0.0);
- WRITEF(gcp->buf, FrontDiffuseColorBlue, 0.0);
- WRITEF(gcp->buf, BackDiffuseColorRed, 0.0);
- WRITEF(gcp->buf, BackDiffuseColorGreen, 0.0);
- WRITEF(gcp->buf, BackDiffuseColorBlue, 0.0);
+ WRITEF(gcp->buf, FrontAmbientColorRed, 0.2);
+ WRITEF(gcp->buf, FrontAmbientColorGreen, 0.2);
+ WRITEF(gcp->buf, FrontAmbientColorBlue, 0.2);
+ WRITEF(gcp->buf, BackAmbientColorRed, 0.2);
+ WRITEF(gcp->buf, BackAmbientColorGreen, 0.2);
+ WRITEF(gcp->buf, BackAmbientColorBlue, 0.2);
+ WRITEF(gcp->buf, FrontDiffuseColorRed, 0.8);
+ WRITEF(gcp->buf, FrontDiffuseColorGreen, 0.8);
+ WRITEF(gcp->buf, FrontDiffuseColorBlue, 0.8);
+ WRITEF(gcp->buf, BackDiffuseColorRed, 0.8);
+ WRITEF(gcp->buf, BackDiffuseColorGreen, 0.8);
+ WRITEF(gcp->buf, BackDiffuseColorBlue, 0.8);
WRITEF(gcp->buf, FrontSpecularColorRed, 0.0);
WRITEF(gcp->buf, FrontSpecularColorGreen, 0.0);
WRITEF(gcp->buf, FrontSpecularColorBlue, 0.0);
@@ -275,11 +284,11 @@ void gammaInitHW(gammaContextPrivate *gcp)
WRITEF(gcp->buf, BackEmissiveColorRed, 0.0);
WRITEF(gcp->buf, BackEmissiveColorGreen, 0.0);
WRITEF(gcp->buf, BackEmissiveColorBlue, 0.0);
- WRITEF(gcp->buf, SceneAmbientColorRed, 0.0);
- WRITEF(gcp->buf, SceneAmbientColorGreen, 0.0);
- WRITEF(gcp->buf, SceneAmbientColorBlue, 0.0);
- WRITEF(gcp->buf, FrontAlpha, 0.0);
- WRITEF(gcp->buf, BackAlpha, 0.0);
+ WRITEF(gcp->buf, SceneAmbientColorRed, 0.2);
+ WRITEF(gcp->buf, SceneAmbientColorGreen, 0.2);
+ WRITEF(gcp->buf, SceneAmbientColorBlue, 0.2);
+ WRITEF(gcp->buf, FrontAlpha, 1.0);
+ WRITEF(gcp->buf, BackAlpha, 1.0);
CHECK_DMA_BUFFER(nullCC, gcp, 8);
WRITE(gcp->buf, PointMode, (PM_AntialiasDisable |
@@ -319,28 +328,28 @@ void gammaInitHW(gammaContextPrivate *gcp)
WRITE(gcp->buf, Light14Mode, LNM_Off);
WRITE(gcp->buf, Light15Mode, LNM_Off);
- CHECK_DMA_BUFFER(nullCC, gcp, 21);
- WRITEF(gcp->buf, FrontAmbientColorRed, 1.0);
- WRITEF(gcp->buf, FrontAmbientColorGreen, 1.0);
- WRITEF(gcp->buf, FrontAmbientColorBlue, 1.0);
- WRITEF(gcp->buf, BackAmbientColorRed, 1.0);
- WRITEF(gcp->buf, BackAmbientColorGreen, 1.0);
- WRITEF(gcp->buf, BackAmbientColorBlue, 1.0);
- WRITEF(gcp->buf, FrontDiffuseColorRed, 1.0);
- WRITEF(gcp->buf, FrontDiffuseColorGreen, 1.0);
- WRITEF(gcp->buf, FrontDiffuseColorBlue, 1.0);
- WRITEF(gcp->buf, BackDiffuseColorRed, 1.0);
- WRITEF(gcp->buf, BackDiffuseColorGreen, 1.0);
- WRITEF(gcp->buf, BackDiffuseColorBlue, 1.0);
- WRITEF(gcp->buf, FrontSpecularColorRed, 0.0);
- WRITEF(gcp->buf, FrontSpecularColorGreen, 0.0);
- WRITEF(gcp->buf, FrontSpecularColorBlue, 0.0);
- WRITEF(gcp->buf, BackSpecularColorRed, 0.0);
- WRITEF(gcp->buf, BackSpecularColorGreen, 0.0);
- WRITEF(gcp->buf, BackSpecularColorBlue, 0.0);
- WRITEF(gcp->buf, SceneAmbientColorRed, 0.0);
- WRITEF(gcp->buf, SceneAmbientColorGreen, 0.0);
- WRITEF(gcp->buf, SceneAmbientColorBlue, 0.0);
+ CHECK_DMA_BUFFER(nullCC, gcp, 22);
+ WRITEF(gcp->buf, Light0AmbientIntensityBlue, 0.0);
+ WRITEF(gcp->buf, Light0AmbientIntensityGreen, 0.0);
+ WRITEF(gcp->buf, Light0AmbientIntensityRed, 0.0);
+ WRITEF(gcp->buf, Light0DiffuseIntensityBlue, 1.0);
+ WRITEF(gcp->buf, Light0DiffuseIntensityGreen, 1.0);
+ WRITEF(gcp->buf, Light0DiffuseIntensityRed, 1.0);
+ WRITEF(gcp->buf, Light0SpecularIntensityBlue, 1.0);
+ WRITEF(gcp->buf, Light0SpecularIntensityGreen, 1.0);
+ WRITEF(gcp->buf, Light0SpecularIntensityRed, 1.0);
+ WRITEF(gcp->buf, Light0SpotlightDirectionZ, 0.0);
+ WRITEF(gcp->buf, Light0SpotlightDirectionY, 0.0);
+ WRITEF(gcp->buf, Light0SpotlightDirectionX, -1.0);
+ WRITEF(gcp->buf, Light0SpotlightExponent, 0.0);
+ WRITEF(gcp->buf, Light0PositionZ, 0.0);
+ WRITEF(gcp->buf, Light0PositionY, 0.0);
+ WRITEF(gcp->buf, Light0PositionX, 1.0);
+ WRITEF(gcp->buf, Light0PositionW, 0.0);
+ WRITEF(gcp->buf, Light0CosSpotlightCutoffAngle, -1.0);
+ WRITEF(gcp->buf, Light0ConstantAttenuation, 1.0);
+ WRITEF(gcp->buf, Light0LinearAttenuation, 0.0);
+ WRITEF(gcp->buf, Light0QuadraticAttenuation,0.0);
CHECK_DMA_BUFFER(nullCC, gcp, 6);
WRITEF(gcp->buf, ViewPortScaleX, (gcp->w)/2.0);
diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_matrix.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_matrix.c
index f6c166609..17220fbb4 100644
--- a/xc/lib/GL/mesa/src/drv/gamma/gamma_matrix.c
+++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_matrix.c
@@ -163,9 +163,7 @@ void gammaLoadHWMatrix(void)
WRITEF(gCCPriv->buf, ModelViewMatrix13, gCCPriv->ModelView[13]);
WRITEF(gCCPriv->buf, ModelViewMatrix14, gCCPriv->ModelView[14]);
WRITEF(gCCPriv->buf, ModelViewMatrix15, gCCPriv->ModelView[15]);
- /* Fall through to load ModelViewProjectionMatrix */
#endif
-
case GL_PROJECTION:
CHECK_DMA_BUFFER(gCC, gCCPriv, 16);
WRITEF(gCCPriv->buf,
diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_regs.h b/xc/lib/GL/mesa/src/drv/gamma/gamma_regs.h
index 3dd4b8783..b13dbdba5 100644
--- a/xc/lib/GL/mesa/src/drv/gamma/gamma_regs.h
+++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_regs.h
@@ -163,6 +163,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define FBWriteModeEnable 0x00000001
#define FBW_UploadColorData 0x00000008
+/* FogMode */
+#define FogModeDisable 0x00000000
+#define FogModeEnable 0x00000001
+
/* LBWriteMode */
#define LBWriteModeDisable 0x00000000
#define LBWriteModeEnable 0x00000001
@@ -391,14 +395,17 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define GM_FogLinear 0x00000000
#define GM_FogExp 0x00000004
#define GM_FogExpSquared 0x00000008
+#define GM_FogMask 0x0000000C
#define GM_FrontPolyPoint 0x00000000
#define GM_FrontPolyLine 0x00000010
#define GM_FrontPolyFill 0x00000020
#define GM_BackPolyPoint 0x00000000
#define GM_BackPolyLine 0x00000040
#define GM_BackPolyFill 0x00000080
+#define GM_FB_PolyMask 0x000000F0
#define GM_FrontFaceCW 0x00000000
#define GM_FrontFaceCCW 0x00000100
+#define GM_FFMask 0x00000100
#define GM_PolyCullDisable 0x00000000
#define GM_PolyCullEnable 0x00000200
#define GM_PolyCullFront 0x00000000
@@ -480,18 +487,44 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* LightingMode */
#define LightingModeDisable 0x00000000
#define LightingModeEnable 0x00000001
+#define LightingModeTwoSides 0x00000002
+#define LightingModeLocalViewer 0x00000008
+
+/* Light0Mode */
+#define Light0ModeDisable 0x00000000
+#define Light0ModeEnable 0x00000001
+#define Light0ModeSpotLight 0x00000002
+#define Light0ModeAttenuation 0x00000004
+#define Light0ModeLocal 0x00000008
+
+/* Light0Mode */
+#define Light1ModeDisable 0x00000000
+#define Light1ModeEnable 0x00000001
+#define Light1ModeSpotLight 0x00000002
+#define Light1ModeAttenuation 0x00000004
+#define Light1ModeLocal 0x00000008
/* ColorMaterialMode */
#define ColorMaterialModeDisable 0x00000000
#define ColorMaterialModeEnable 0x00000001
+#define ColorMaterialModeFront 0x00000000
+#define ColorMaterialModeBack 0x00000002
+#define ColorMaterialModeFrontAndBack 0x00000004
+#define ColorMaterialModeEmission 0x00000000
+#define ColorMaterialModeAmbient 0x00000008
+#define ColorMaterialModeDiffuse 0x00000010
+#define ColorMaterialModeSpecular 0x00000018
+#define ColorMaterialModeAmbAndDiff 0x00000020
+#define ColorMaterialModeMask 0x0000003e
/* MaterialMode */
#define MaterialModeDisable 0x00000000
#define MaterialModeEnable 0x00000001
+#define MaterialModeTwoSides 0x00000080
/* DeltaMode */
#define DM_Target300SX 0x00000000
-#define DM_Target300TXMX 0x00000001
+#define DM_Target500TXMX 0x00000001
#define DM_Depth16 0x00000004
#define DM_Depth24 0x00000008
#define DM_Depth32 0x0000000c
diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_texture.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_texture.c
index 14a993969..ffa437ed2 100644
--- a/xc/lib/GL/mesa/src/drv/gamma/gamma_texture.c
+++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_texture.c
@@ -34,6 +34,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef GLX_DIRECT_RENDERING
+#include <Xarch.h>
#include <X11/Xlibint.h>
#include "gamma_init.h"
#include <string.h>
@@ -74,7 +75,11 @@ void gammaTOInit(gammaTexObj *t)
t->TextureFilterMode = (TextureFilterModeDisable);
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
t->TextureFormat = (TF_LittleEndian |
+#else
+ t->TextureFormat = (TF_BigEndian |
+#endif
TF_16Bit_565 |
TF_ColorOrder_RGB |
TF_Compnents_4 |
diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c
index 450b081a3..b199bc073 100644
--- a/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c
+++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c
@@ -30,6 +30,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* Authors:
* Kevin E. Martin <kevin@precisioninsight.com>
* Brian Paul <brian@precisioninsight.com>
+ * Alan Hourihane <Alan.Hourihane@btinternet.com>
*/
#ifdef GLX_DIRECT_RENDERING
@@ -38,6 +39,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "gamma_init.h"
#include "gamma_gl.h"
#include "glapi.h"
+#include "glint_dri.h"
#include "context.h"
#include "mmath.h"
@@ -144,6 +146,7 @@ GLboolean XMesaCreateContext( Display *dpy,
gammaContextPrivate *cPriv;
__DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv;
gammaScreenPrivate *gPriv = (gammaScreenPrivate *)driScrnPriv->private;
+ GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)driScrnPriv->pDevPriv;
if (!Dispatch) {
GLuint size = _glapi_get_dispatch_table_size() * sizeof(GLvoid *);
@@ -194,27 +197,26 @@ GLboolean XMesaCreateContext( Display *dpy,
cPriv->ModelViewProj[i] =
cPriv->Texture[i] = 0.0;
- /*
- ** NOT_DONE: The 0xe4 in LBReadMode and FBReadMode refers to the
- ** partial products for the 640x480 mode. We will need to look up
- ** the partial products in a table (c.f., glint_driver.c) to support
- ** other FB sizes.
- */
cPriv->LBReadMode = (LBReadSrcDisable |
LBReadDstDisable |
LBDataTypeDefault |
LBWindowOriginBot |
- LBScanLineInt2 |
- 0xe4); /* NOT_DONE: 640x480 partial products */
+ gDRIPriv->pprod);
cPriv->FBReadMode = (FBReadSrcDisable |
FBReadDstDisable |
FBDataTypeDefault |
FBWindowOriginBot |
- FBScanLineInt2 |
- 0xe4); /* NOT_DONE: 640x480 partial products */
-
- cPriv->FBWindowBase = driScrnPriv->fbWidth * (driScrnPriv->fbHeight/2 - 1);
- cPriv->LBWindowBase = driScrnPriv->fbWidth * (driScrnPriv->fbHeight/2 - 1);
+ gDRIPriv->pprod);
+
+ if (gDRIPriv->numMXDevices == 2) {
+ cPriv->LBReadMode |= LBScanLineInt2;
+ cPriv->FBReadMode |= FBScanLineInt2;
+ cPriv->FBWindowBase =driScrnPriv->fbWidth*(driScrnPriv->fbHeight/2 - 1);
+ cPriv->LBWindowBase =driScrnPriv->fbWidth*(driScrnPriv->fbHeight/2 - 1);
+ } else {
+ cPriv->FBWindowBase = driScrnPriv->fbWidth * driScrnPriv->fbHeight;
+ cPriv->LBWindowBase = driScrnPriv->fbWidth * driScrnPriv->fbHeight;
+ }
cPriv->Begin = (B_AreaStippleDisable |
B_LineStippleDisable |
@@ -306,7 +308,7 @@ GLboolean XMesaCreateContext( Display *dpy,
4, 1,
gammaTOLoad,
gammaTOLoadSub);
-
+
cPriv->curTexObj = gammaTOFind(0);
cPriv->curTexObj1D = cPriv->curTexObj;
cPriv->curTexObj2D = cPriv->curTexObj;
@@ -334,7 +336,7 @@ GLboolean XMesaCreateContext( Display *dpy,
cPriv->DeltaMode = (DM_SubPixlCorrectionEnable |
DM_SmoothShadingEnable |
- DM_Target300TXMX);
+ DM_Target500TXMX);
switch (cPriv->DepthSize) {
case 16:
@@ -352,6 +354,14 @@ GLboolean XMesaCreateContext( Display *dpy,
cPriv->gammaScrnPriv = gPriv;
+ cPriv->LightingMode = LightingModeDisable;
+ cPriv->Light0Mode = LNM_Off;
+ cPriv->Light1Mode = LNM_Off;
+
+ cPriv->MaterialMode = MaterialModeDisable;
+
+ cPriv->ScissorMode = UserScissorDisable | ScreenScissorDisable;
+
driContextPriv->driverPrivate = cPriv;
/* Initialize the HW to a known state */
@@ -491,7 +501,6 @@ GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv)
{
-
if (driContextPriv) {
gCC = driContextPriv;
gCCPriv = (gammaContextPrivate *) driContextPriv->driverPrivate;
@@ -503,6 +512,8 @@ GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv,
WRITE(gCCPriv->buf, GLINTWindow, gCCPriv->Window);
_glapi_set_dispatch(Dispatch);
+
+ _gamma_Viewport(0, 0, driDrawPriv->w, driDrawPriv->h);
} else {
gCC = NULL;
gCCPriv = NULL;
diff --git a/xc/lib/GL/mesa/src/drv/i810/Imakefile b/xc/lib/GL/mesa/src/drv/i810/Imakefile
index 7260846fd..6b72c80e4 100644
--- a/xc/lib/GL/mesa/src/drv/i810/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/i810/Imakefile
@@ -1,4 +1,6 @@
+#include <Threads.tmpl>
+
#define DoNormalLib NormalLibGlx
#define DoSharedLib SharedLibGlx
#define DoExtraLib SharedLibGlx
@@ -9,13 +11,22 @@
ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
#endif
+#if defined(LinuxArchitecture)
+OS_SUBDIR = linux
+#endif
+#if defined(FreeBSDArchitecture)
+OS_SUBDIR = bsd
+#endif
+
#if BuildXF86DRI
DRI_DEFINES = GlxDefines -DDRIVERTS
DRI_INCLUDES = -I../../../../dri -I../../../../glx \
+ -I../../../dri \
-I$(TOP)/include -I$(TOP)/include/GL \
-I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri \
-I$(XF86DRIVERSRC)/i810 \
- -I../../../include -I../.. -I../common -I../../X
+ -I../../../include -I../.. -I../common -I../../X \
+ -I$(XF86OSSRC)/$(OS_SUBDIR)/drm/kernel
#endif
MESA_INCLUDES = -I. -I.. -I../../include
@@ -23,20 +34,244 @@ MESA_INCLUDES = -I. -I.. -I../../include
DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES)
- INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) \
- -I/usr/include/glide
- DRISRCS = i810_xmesa.c i810clear.c \
- i810dd.c i810depth.c i810dma.c i810ring.c \
- i810pipeline.c i810span.c i810state.c i810swap.c \
- i810tex.c i810tris.c i810vb.c i810fastpath.c
+ INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES)
+
+ DRISRCS = ../../../dri/dri_mesa.c \
+ ../../../../dri/dri_tmm.c
+
+ DRIOBJS = ../../../dri/dri_mesa.o \
+ ../../../../dri/dri_tmm.o
+
+ DRMSRCS = ../../../../dri/drm/xf86drm.c \
+ ../../../../dri/drm/xf86drmHash.c \
+ ../../../../dri/drm/xf86drmRandom.c \
+ ../../../../dri/drm/xf86drmSL.c
+
+ DRMOBJS = ../../../../dri/drm/xf86drm.o \
+ ../../../../dri/drm/xf86drmHash.o \
+ ../../../../dri/drm/xf86drmRandom.o \
+ ../../../../dri/drm/xf86drmSL.o
+
+
+ I810SRCS = i810_xmesa.c \
+ i810dd.c \
+ i810pipeline.c i810span.c i810state.c \
+ i810tex.c i810tris.c i810vb.c i810fastpath.c i810ioctl.c
+
+ I810OBJS = i810_xmesa.o \
+ i810dd.o \
+ i810pipeline.o i810span.o i810state.o \
+ i810tex.o i810tris.o i810vb.o i810fastpath.o i810ioctl.o
+
+ MESASRCS = ../../aatriangle.c \
+ ../../accum.c \
+ ../../alpha.c \
+ ../../alphabuf.c \
+ ../../attrib.c \
+ ../../bbox.c \
+ ../../bitmap.c \
+ ../../blend.c \
+ ../../buffers.c \
+ ../../clip.c \
+ ../../colortab.c \
+ ../../config.c \
+ ../../context.c \
+ ../../copypix.c \
+ ../../cva.c \
+ ../../debug_xform.c \
+ ../../depth.c \
+ ../../dlist.c \
+ ../../drawpix.c \
+ ../../enable.c \
+ ../../enums.c \
+ ../../eval.c \
+ ../../extensions.c \
+ ../../feedback.c \
+ ../../fog.c \
+ ../../get.c \
+ ../../glapi.c \
+ ../../glapinoop.c \
+ ../../glthread.c \
+ ../../hash.c \
+ ../../image.c \
+ ../../imaging.c \
+ ../../light.c \
+ ../../lines.c \
+ ../../logic.c \
+ ../../masking.c \
+ ../../matrix.c \
+ ../../mem.c \
+ ../../mmath.c \
+ ../../pb.c \
+ ../../pipeline.c \
+ ../../pixel.c \
+ ../../pixeltex.c \
+ ../../points.c \
+ ../../polygon.c \
+ ../../quads.c \
+ ../../rastpos.c \
+ ../../readpix.c \
+ ../../rect.c \
+ ../../scissor.c \
+ ../../shade.c \
+ ../../span.c \
+ ../../stages.c \
+ ../../state.c \
+ ../../stencil.c \
+ ../../teximage.c \
+ ../../texobj.c \
+ ../../texstate.c \
+ ../../texture.c \
+ ../../texutil.c \
+ ../../translate.c \
+ ../../triangle.c \
+ ../../varray.c \
+ ../../vb.c \
+ ../../vbcull.c \
+ ../../vbfill.c \
+ ../../vbindirect.c \
+ ../../vbrender.c \
+ ../../vbxform.c \
+ ../../vector.c \
+ ../../vertices.c \
+ ../../winpos.c \
+ ../../xform.c \
+ ../../zoom.c \
+ ../../X86/common_x86.c
+
+ MESAOBJS = ../../aatriangle.o \
+ ../../accum.o \
+ ../../alpha.o \
+ ../../alphabuf.o \
+ ../../attrib.o \
+ ../../bbox.o \
+ ../../bitmap.o \
+ ../../blend.o \
+ ../../buffers.o \
+ ../../clip.o \
+ ../../colortab.o \
+ ../../config.o \
+ ../../context.o \
+ ../../copypix.o \
+ ../../cva.o \
+ ../../debug_xform.o \
+ ../../depth.o \
+ ../../dlist.o \
+ ../../drawpix.o \
+ ../../enable.o \
+ ../../enums.o \
+ ../../eval.o \
+ ../../extensions.o \
+ ../../feedback.o \
+ ../../fog.o \
+ ../../get.o \
+ ../../hash.o \
+ ../../hint.o \
+ ../../image.o \
+ ../../imaging.o \
+ ../../light.o \
+ ../../lines.o \
+ ../../logic.o \
+ ../../masking.o \
+ ../../matrix.o \
+ ../../mem.o \
+ ../../mmath.o \
+ ../../pb.o \
+ ../../pipeline.o \
+ ../../pixel.o \
+ ../../pixeltex.o \
+ ../../points.o \
+ ../../polygon.o \
+ ../../quads.o \
+ ../../rastpos.o \
+ ../../readpix.o \
+ ../../rect.o \
+ ../../scissor.o \
+ ../../shade.o \
+ ../../span.o \
+ ../../stages.o \
+ ../../state.o \
+ ../../stencil.o \
+ ../../teximage.o \
+ ../../texobj.o \
+ ../../texstate.o \
+ ../../texture.o \
+ ../../texutil.o \
+ ../../translate.o \
+ ../../triangle.o \
+ ../../varray.o \
+ ../../vb.o \
+ ../../vbcull.o \
+ ../../vbfill.o \
+ ../../vbindirect.o \
+ ../../vbrender.o \
+ ../../vbxform.o \
+ ../../vector.o \
+ ../../vertices.o \
+ ../../winpos.o \
+ ../../xform.o \
+ ../../zoom.o
- DRIOBJS = i810_xmesa.o i810clear.o \
- i810dd.o i810depth.o i810dma.o i810ring.o \
- i810pipeline.o i810span.o i810state.o i810swap.o \
- i810tex.o i810tris.o i810vb.o i810fastpath.o
+#ifdef i386Architecture
+ X86_SRCS = ../../X86/x86.c \
+ ../../X86/x86a.S \
+ ../../X86/common_x86.c \
+ ../../X86/common_x86asm.S \
+ ../../X86/vertex.S
+
+ X86_OBJS = ../../X86/x86.o \
+ ../../X86/x86a.o \
+ ../../X86/common_x86.o \
+ ../../X86/common_x86asm.o \
+ ../../X86/vertex.o
+
+ MMX_SRCS = ../../X86/mmx_blend.S
+
+ MMX_OBJS = ../../X86/mmx_blend.o
+
+XCOMM Disabling 3Dnow code for the time being.
+#if 0
+ 3DNOW_SRCS = ../../X86/3dnow.c \
+ ../../X86/3dnow_norm_raw.S \
+ ../../X86/3dnow_xform_masked1.S \
+ ../../X86/3dnow_xform_masked2.S \
+ ../../X86/3dnow_xform_masked3.S \
+ ../../X86/3dnow_xform_masked4.S \
+ ../../X86/3dnow_xform_raw1.S \
+ ../../X86/3dnow_xform_raw2.S \
+ ../../X86/3dnow_xform_raw3.S \
+ ../../X86/3dnow_xform_raw4.S \
+ ../../X86/vertex_3dnow.S
+
+ 3DNOW_OBJS = ../../X86/3dnow.o \
+ ../../X86/3dnow_norm_raw.o \
+ ../../X86/3dnow_xform_masked1.o \
+ ../../X86/3dnow_xform_masked2.o \
+ ../../X86/3dnow_xform_masked3.o \
+ ../../X86/3dnow_xform_masked4.o \
+ ../../X86/3dnow_xform_raw1.o \
+ ../../X86/3dnow_xform_raw2.o \
+ ../../X86/3dnow_xform_raw3.o \
+ ../../X86/3dnow_xform_raw4.o \
+ ../../X86/vertex_3dnow.o
+#endif
+
+#endif
+
+ ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS)
+ ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS)
+
+ COMMONSRCS = ../common/mm.c ../common/hwlog.c
+ COMMONOBJS = ../common/mm.o ../common/hwlog.o
+
+ SRCS = $(DRISRCS) $(DRMSRCS) $(MESASRCS) $(ASMSRCS) $(COMMONSRCS) $(I810SRCS)
+ OBJS = $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) $(ASMOBJS) $(COMMONOBJS) $(I810OBJS)
+
+REQUIREDLIBS += -lm
+#if !GlxBuiltInI810
+REQUIREDLIBS += -L../../../.. -lGL
+#endif
- SRCS = $(DRISRCS)
- OBJS = $(DRIOBJS)
#if !GlxUseBuiltInDRIDriver
#undef DoNormalLib NormalLibGlx
@@ -57,7 +292,7 @@ LIBNAME = i810_dri.so
ALL_OBJS = $(OBJS)
ALL_DEPS = DONE
SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS))
-InstallDynamicModule($(LIBNAME),$(MODULEDIR),.)
+InstallDynamicModule($(LIBNAME),$(MODULEDIR)/dri,.)
#endif
DependTarget()
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h b/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h
index 8e6942497..a4b947b30 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h
@@ -108,6 +108,8 @@
#define LCS_UPDATE_LINEWIDTH (0x1<<15)
#define LCS_LINEWIDTH_MASK (0x7<<12)
#define LCS_LINEWIDTH_SHIFT 12
+#define LCS_LINEWIDTH_0_5 (0x1<<12)
+#define LCS_LINEWIDTH_1_0 (0x2<<12)
#define LCS_UPDATE_ALPHA_INTERP (0x1<<11)
#define LCS_ALPHA_FLAT (0x0<<10)
#define LCS_ALPHA_INTERP (0x1<<10)
@@ -616,9 +618,6 @@ typedef struct {
#define DV_PF_555 (0x1<<8)
#define DV_PF_565 (0x2<<8)
-
-
-
#define GFX_OP_ANTIALIAS ((0x3<<29)|(0x6<<24))
#define AA_UPDATE_EDGEFLAG (1<<13)
#define AA_ENABLE_EDGEFLAG (1<<12)
@@ -641,84 +640,16 @@ typedef struct {
#define ST1_ENABLE (1<<16)
#define ST1_MASK (0xffff)
+#define I810_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
-/* Indices into buf.Setup where various bits of state are mirrored per
- * context and per buffer. These can be fired at the card as a unit,
- * or in a piecewise fashion as required.
- */
-
-/* Destbuffer state
- * - backbuffer linear offset and pitch -- invarient in the current dri
- * - zbuffer linear offset and pitch -- also invarient
- * - drawing origin in back and depth buffers.
- *
- * Keep the depth/back buffer state here to acommodate private buffers
- * in the future.
- */
-#define I810_DESTREG_DI0 0 /* CMD_OP_DESTBUFFER_INFO (2 dwords) */
-#define I810_DESTREG_DI1 1
-#define I810_DESTREG_ZB0 2 /* CMD_OP_Z_BUFFER_INFO */
-#define I810_DESTREG_ZB1 3 /* CMD_OP_Z_BUFFER_INFO */
-#define I810_DESTREG_DV0 4 /* GFX_OP_DESTBUFFER_VARS (2 dwords) */
-#define I810_DESTREG_DV1 5
-#define I810_DESTREG_DR0 6 /* GFX_OP_DRAWRECT_INFO (4 dwords) */
-#define I810_DESTREG_DR1 7
-#define I810_DESTREG_DR2 8
-#define I810_DESTREG_DR3 9
-#define I810_DESTREG_DR4 10
-
-#define I810_DEST_SETUP_SIZE (11+1)
-
-/* Context state
- */
-#define I810_CTXREG_VF 0 /* GFX_OP_VERTEX_FMT */
-#define I810_CTXREG_MT 1 /* GFX_OP_MAP_TEXELS */
-#define I810_CTXREG_MC0 2 /* GFX_OP_MAP_COLOR_STAGES - stage 0 */
-#define I810_CTXREG_MC1 3 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */
-#define I810_CTXREG_MC2 4 /* GFX_OP_MAP_COLOR_STAGES - stage 2 */
-#define I810_CTXREG_MA0 5 /* GFX_OP_MAP_ALPHA_STAGES - stage 0 */
-#define I810_CTXREG_MA1 6 /* GFX_OP_MAP_ALPHA_STAGES - stage 1 */
-#define I810_CTXREG_MA2 7 /* GFX_OP_MAP_ALPHA_STAGES - stage 2 */
-#define I810_CTXREG_SDM 8 /* GFX_OP_SRC_DEST_MONO */
-#define I810_CTXREG_CF0 9 /* GFX_OP_COLOR_FACTOR */
-#define I810_CTXREG_CF1 10
-#define I810_CTXREG_FOG 11 /* GFX_OP_FOG_COLOR */
-#define I810_CTXREG_B1 12 /* GFX_OP_BOOL_1 */
-#define I810_CTXREG_B2 13 /* GFX_OP_BOOL_2 */
-#define I810_CTXREG_LCS 14 /* GFX_OP_LINEWIDTH_CULL_SHADE_MODE */
-#define I810_CTXREG_PV 15 /* GFX_OP_PV_RULE -- Invarient! */
-#define I810_CTXREG_ZA 16 /* GFX_OP_ZBIAS_ALPHAFUNC */
-#define I810_CTXREG_ST0 17 /* GFX_OP_STIPPLE */
-#define I810_CTXREG_ST1 18
-#define I810_CTXREG_AA 19 /* GFX_OP_ANTIALIAS */
-#define I810_CTX_SETUP_SIZE (20) /* pad to qword */
-
-
-/* Cliprect state - keep seperate from context as it is used for
- * drawing triangles to the shared backbuffer, and
- * changes more frequently than the 'normal' context.
- */
-#define I810_CLIPREG_SCI0 0 /* GFX_OP_SCISSOR_INFO (3 dwords) */
-#define I810_CLIPREG_SCI1 1
-#define I810_CLIPREG_SCI2 2
-#define I810_CLIPREG_SC 3 /* GFX_OP_SCISSOR */
-
-#define I810_CLIP_SETUP_SIZE 4
-
-/* Texture state (per tex_buffer)
- */
-#define I810_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (4 dwords) */
-#define I810_TEXREG_MI1 1
-#define I810_TEXREG_MI2 2
-#define I810_TEXREG_MI3 3
-#define I810_TEXREG_MF 4 /* GFX_OP_MAP_FILTER */
-#define I810_TEXREG_MLC 5 /* GFX_OP_MAP_LOD_CTL */
-#define I810_TEXREG_MLL 6 /* GFX_OP_MAP_LOD_LIMITS */
-#define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */
-
-#define I810_TEX_SETUP_SIZE 8
+#define I810PACKCOLOR4444(r,g,b,a) \
+ ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
+#define I810PACKCOLOR1555(r,g,b,a) \
+ ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
+ ((a) ? 0x8000 : 0))
-#define I810_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
+#define I810PACKCOLOR565(r,g,b) \
+ ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c b/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c
index 7545a325f..8b439e52c 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c
@@ -47,7 +47,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "i810tex.h"
#include "i810span.h"
#include "i810tris.h"
-#include "i810swap.h"
#include "i810pipeline.h"
#include "i810ioctl.h"
@@ -74,8 +73,40 @@ int I810_DEBUG = (0
static i810ContextPtr i810Ctx = 0;
-i810Glx_t i810glx;
+/* These functions are accessed externally to the driver:
+ *
+ * XMesaInitDriver
+ * XMesaResetDriver
+ * XMesaCreateVisual
+ * XMesaDestroyVisual
+ * XMesaCreateContext
+ * XMesaDestroyContext
+ * XMesaCreateWindowBuffer
+ * XMesaCreatePixmapBuffer
+ * XMesaDestroyBuffer
+ * XMesaSwapBuffers
+ * XMesaMakeCurrent
+ *
+ */
+
+
+static drmBufMapPtr i810_create_empty_buffers(void)
+{
+ drmBufMapPtr retval;
+
+ retval = (drmBufMapPtr)Xmalloc(sizeof(drmBufMap));
+ if(retval == NULL) return NULL;
+ memset(retval, 0, sizeof(drmBufMap));
+ retval->list = (drmBufPtr)Xmalloc(sizeof(drmBuf) * I810_DMA_BUF_NR);
+ if(retval->list == NULL) {
+ Xfree(retval);
+ return NULL;
+ }
+ memset(retval->list, 0, sizeof(drmBuf) * I810_DMA_BUF_NR);
+ fprintf(stderr, "retval : %p, retval->list : %p\n", retval, retval->list);
+ return retval;
+}
GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
{
@@ -148,13 +179,13 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
fprintf(stderr, "Tex heap size %x, granularity %x bytes\n",
i810Screen->textureSize, 1<<(i810Screen->logTextureGranularity));
- i810Screen->bufs = drmMapBufs(sPriv->fd);
- if (!i810Screen->bufs) {
+ i810Screen->bufs = i810_create_empty_buffers();
+ if(i810Screen->bufs == NULL)
+ {
Xfree(i810Screen);
- sPriv->private = NULL;
return GL_FALSE;
}
-
+
i810Screen->back.handle = gDRIPriv->backbuffer;
i810Screen->back.size = gDRIPriv->backbufferSize;
@@ -198,11 +229,6 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
}
- /* Ditch i810glx in favor of i810Screen?
- */
- memset(&i810glx, 0, sizeof(i810glx));
- i810glx.texVirtual = i810Screen->tex.map;
-
i810DDFastPathInit();
i810DDTrifuncInit();
i810DDSetupInit();
@@ -274,13 +300,13 @@ GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis,
* in memory at once.
*/
if (i810Screen->textureSize < 2*1024*1024) {
- ctx->Const.MaxTextureLevels = 8;
+ ctx->Const.MaxTextureLevels = 9;
ctx->Const.MaxTextureSize = 1<<8;
} else if (i810Screen->textureSize < 8*1024*1024) {
- ctx->Const.MaxTextureLevels = 9;
+ ctx->Const.MaxTextureLevels = 10;
ctx->Const.MaxTextureSize = 1<<9;
} else {
- ctx->Const.MaxTextureLevels = 10;
+ ctx->Const.MaxTextureLevels = 11;
ctx->Const.MaxTextureSize = 1<<10;
}
@@ -415,23 +441,6 @@ void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv)
i810SwapBuffers(imesa);
}
-static void i810InitClipRects( i810ContextPtr imesa )
-{
- switch (imesa->numClipRects) {
- case 0:
- imesa->ClipSetup[I810_CLIPREG_SC] = ( GFX_OP_SCISSOR |
- SC_UPDATE_SCISSOR );
- imesa->ClipSetup[I810_CLIPREG_SCI1] = 0;
- imesa->ClipSetup[I810_CLIPREG_SCI2] = 0;
- break;
- case 1:
- break;
- default:
- break;
- }
- imesa->dirty |= I810_EMIT_CLIPRECT;
-}
-
void i810XMesaSetFrontClipRects( i810ContextPtr imesa )
@@ -440,12 +449,12 @@ void i810XMesaSetFrontClipRects( i810ContextPtr imesa )
imesa->numClipRects = dPriv->numClipRects;
imesa->pClipRects = dPriv->pClipRects;
+ imesa->dirty |= I810_UPLOAD_CLIPRECTS;
imesa->drawX = dPriv->x;
imesa->drawY = dPriv->y;
imesa->drawMap = imesa->driScreen->pFB;
i810EmitDrawingRectangle( imesa );
- i810InitClipRects( imesa );
}
@@ -477,7 +486,7 @@ void i810XMesaSetBackClipRects( i810ContextPtr imesa )
imesa->drawMap = imesa->i810Screen->back.map;
i810EmitDrawingRectangle( imesa );
- i810InitClipRects( imesa );
+ imesa->dirty |= I810_UPLOAD_CLIPRECTS;
if (I810_DEBUG & DEBUG_VERBOSE_DRI)
for (i = 0 ; i < imesa->numClipRects ; i++)
@@ -519,29 +528,27 @@ GLboolean XMesaUnbindContext(__DRIcontextPrivate *driContextPriv)
}
-/* This looks buggy to me - the 'b' variable isn't used anywhere...
- * Hmm - It seems that the drawable is already hooked in to
- * driDrawablePriv.
- */
GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv,
- __DRIdrawablePrivate *driDrawPriv,
- __DRIdrawablePrivate *driReadPriv)
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv)
{
if (driContextPriv) {
i810Ctx = (i810ContextPtr) driContextPriv->driverPrivate;
-
- gl_make_current2(i810Ctx->glCtx, driDrawPriv->mesaBuffer, driReadPriv->mesaBuffer);
-
+
+ gl_make_current2(i810Ctx->glCtx, driDrawPriv->mesaBuffer,
+ driReadPriv->mesaBuffer);
+
+
i810Ctx->driDrawable = driDrawPriv;
i810Ctx->dirty = ~0;
-
+
i810XMesaWindowMoved( i810Ctx );
-
+
if (!i810Ctx->glCtx->Viewport.Width)
gl_Viewport(i810Ctx->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h);
-
}
- else {
+ else
+ {
gl_make_current(0,0);
i810Ctx = NULL;
}
@@ -588,10 +595,11 @@ void i810GetLock( i810ContextPtr imesa, GLuint flags )
* more broken than usual.
*/
if (sarea->ctxOwner != me) {
- i810glx.c_ctxlost++;
- imesa->dirty |= I810_UPLOAD_CTX;
- imesa->dirty |= I810_EMIT_CLIPRECT;
- imesa->dirty |= I810_UPLOAD_BUFFERS;
+ imesa->dirty |= (I810_UPLOAD_CTX |
+ I810_UPLOAD_CLIPRECTS |
+ I810_UPLOAD_BUFFERS |
+ I810_UPLOAD_TEX0 |
+ I810_UPLOAD_TEX1);
sarea->ctxOwner = me;
}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810clear.c b/xc/lib/GL/mesa/src/drv/i810/i810clear.c
deleted file mode 100644
index 5ba264059..000000000
--- a/xc/lib/GL/mesa/src/drv/i810/i810clear.c
+++ /dev/null
@@ -1,193 +0,0 @@
-
-
-#include "types.h"
-#include "vbrender.h"
-#include "i810log.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "mm.h"
-#include "i810lib.h"
-#include "i810dd.h"
-#include "i810clear.h"
-#include "i810state.h"
-#include "i810tris.h"
-
-
-
-/* Clear the depthbuffer. Always uses the auxillary cliprects and
- * origin from 'dPriv'.
- */
-static void i810_clear_depthbuffer( GLcontext *ctx,
- GLboolean all,
- GLint cx, GLint cy,
- GLint cwidth, GLint cheight )
-{
- i810ContextPtr imesa = I810_CONTEXT( ctx );
- GLuint zval = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE);
- i810ScreenPrivate *i810Screen = imesa->i810Screen;
- __DRIdrawablePrivate *dPriv = imesa->driDrawable;
-
-/* int _nc = dPriv->numAuxClipRects; */
-/* XF86DRIClipRectPtr box = dPriv->pAuxClipRects; */
-
- int _nc = imesa->numClipRects;
- XF86DRIClipRectPtr box = imesa->pClipRects;
-
- cy = dPriv->h-cy-cheight;
- cx += dPriv->auxX;
- cy += dPriv->auxY;
-
- while (_nc--) {
- GLint x = box[_nc].x1;
- GLint y = box[_nc].y1;
- GLint width = box[_nc].x2 - x;
- GLint height = box[_nc].y2 - y;
-
- if (!all) {
- if (x < cx) width -= cx - x, x = cx;
- if (y < cy) height -= cy - y, y = cy;
- if (x + width > cx + cwidth) width = cx + cwidth - x;
- if (y + height > cy + cheight) height = cy + cheight - y;
- if (width <= 0) continue;
- if (height <= 0) continue;
- }
-
- if (I810_DEBUG&DEBUG_VERBOSE_2D)
- fprintf(stderr, "clear depth rect %d,%d %dx%d\n",
- (int) x, (int) y, (int) width, (int) height);
-
- {
- int start = (i810Screen->depthOffset +
- y * i810Screen->auxPitch +
- x * 2);
-
- BEGIN_BATCH(imesa, 6);
-
- OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 );
- OUT_BATCH( BR13_SOLID_PATTERN |
- (0xF0 << 16) |
- i810Screen->auxPitch );
- OUT_BATCH( (height << 16) | (width * 2));
- OUT_BATCH( start );
- OUT_BATCH( zval );
- OUT_BATCH( 0 );
-
- ADVANCE_BATCH();
- }
- }
-}
-
-
-/* Clear the current drawbuffer. Checks 'imesa' to determine which set of
- * cliprects and origin to use.
- */
-static void i810_clear_colorbuffer( GLcontext *ctx,
- GLboolean all,
- GLint cx, GLint cy,
- GLint cwidth, GLint cheight )
-{
- i810ContextPtr imesa = I810_CONTEXT( ctx );
- GLushort c = imesa->ClearColor;
- i810ScreenPrivate *i810Screen = imesa->i810Screen;
- __DRIdrawablePrivate *dPriv = imesa->driDrawable;
-
- int _nc = imesa->numClipRects;
- XF86DRIClipRectPtr box = imesa->pClipRects;
-
- cy = dPriv->h-cy-cheight;
- cx += imesa->drawX;
- cy += imesa->drawY;
-
- while (_nc--) {
- GLint x = box[_nc].x1;
- GLint y = box[_nc].y1;
- GLint width = box[_nc].x2 - x;
- GLint height = box[_nc].y2 - y;
-
- if (!all) {
- if (x < cx) width -= cx - x, x = cx;
- if (y < cy) height -= cy - y, y = cy;
- if (x + width > cx + cwidth) width = cx + cwidth - x;
- if (y + height > cy + cheight) height = cy + cheight - y;
- if (width <= 0) continue;
- if (height <= 0) continue;
- }
-
- if (I810_DEBUG&DEBUG_VERBOSE_2D)
- fprintf(stderr, "clear color rect %d,%d %dx%d\n",
- (int) x, (int) y, (int) width, (int) height);
-
-
- {
- int start = (imesa->drawOffset +
- y * i810Screen->auxPitch +
- x * i810Screen->cpp);
-
- BEGIN_BATCH( imesa, 6 );
-
- OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 );
- OUT_BATCH( BR13_SOLID_PATTERN |
- (0xF0 << 16) |
- i810Screen->auxPitch );
- OUT_BATCH( (height << 16) | (width * i810Screen->cpp));
- OUT_BATCH( start );
- OUT_BATCH( c );
- OUT_BATCH( 0 );
-
- ADVANCE_BATCH();
- }
- }
-}
-
-
-
-
-/*
- * i810Clear
- *
- * Clear the color and/or depth buffers. If 'all' is GL_TRUE, clear
- * whole buffer, otherwise clear the region defined by the remaining
- * parameters.
- */
-GLbitfield i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
- GLint cx, GLint cy, GLint cwidth, GLint cheight )
-{
- i810ContextPtr imesa = I810_CONTEXT( ctx );
-
- if (I810_DEBUG&DEBUG_VERBOSE_API)
- fprintf(stderr, "i810Clear( %d, %d, %d, %d, %d )\n",
- (int)mask, (int)cx, (int)cy, (int)cwidth, (int)cheight );
-
- LOCK_HARDWARE(imesa);
-
- {
- BEGIN_BATCH( imesa, 2 );
- OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH );
- OUT_BATCH( 0 );
- ADVANCE_BATCH();
- }
-
- if (mask & GL_COLOR_BUFFER_BIT) {
- i810_clear_colorbuffer( ctx, all, cx, cy, cwidth, cheight );
- mask &= ~GL_COLOR_BUFFER_BIT;
- }
-
- if ( (mask & GL_DEPTH_BUFFER_BIT) && ctx->Depth.Mask ) {
- i810_clear_depthbuffer( ctx, all, cx, cy, cwidth, cheight );
- mask &= ~GL_DEPTH_BUFFER_BIT;
- }
-
- {
- BEGIN_BATCH( imesa, 2 );
- OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH );
- OUT_BATCH( 0 );
- ADVANCE_BATCH();
- }
-
- UNLOCK_HARDWARE( imesa );
- return mask;
-}
-
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810clear.h b/xc/lib/GL/mesa/src/drv/i810/i810clear.h
deleted file mode 100644
index aedbf84d9..000000000
--- a/xc/lib/GL/mesa/src/drv/i810/i810clear.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _I810_CLEAR_H
-#define _I810_CLEAR_H
-
-extern GLbitfield i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
- GLint x, GLint y, GLint width, GLint height );
-
-#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810context.h b/xc/lib/GL/mesa/src/drv/i810/i810context.h
index 9f316f6fd..629abf0b8 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810context.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810context.h
@@ -28,24 +28,32 @@
typedef struct i810_context_t i810Context;
typedef struct i810_context_t *i810ContextPtr;
+typedef struct i810_texture_object_t *i810TextureObjectPtr;
#include <X11/Xlibint.h>
#include "dri_tmm.h"
#include "dri_mesaint.h"
#include "dri_mesa.h"
-#include "xmesaP.h"
#include "types.h"
#include "i810_init.h"
-#include "i810_sarea.h"
+#include "drm.h"
+#include "mm.h"
+#include "i810log.h"
#include "i810tex.h"
#include "i810vb.h"
-
-#define I810_FALLBACK_TEXTURE 0x1
-#define I810_FALLBACK_BUFFER 0x2
+/* Reasons to fallback on all primitives. (see also
+ * imesa->IndirectTriangles).
+ */
+#define I810_FALLBACK_TEXTURE 0x1
+#define I810_FALLBACK_DRAW_BUFFER 0x2
+#define I810_FALLBACK_READ_BUFFER 0x4
+#define I810_FALLBACK_COLORMASK 0x8
+#define I810_FALLBACK_STIPPLE 0x10
+#define I810_FALLBACK_SPECULAR 0x20
@@ -53,17 +61,6 @@ typedef struct i810_context_t *i810ContextPtr;
*/
#define I810_NEW_TEXTURE 0x1
-/* for i810ctx.dirty - manage driver->hw state changes, including
- * lost contexts.
- */
-#define I810_REQUIRE_QUIESCENT 0x1
-#define I810_UPLOAD_TEX0IMAGE 0x2
-#define I810_UPLOAD_TEX1IMAGE 0x4
-#define I810_UPLOAD_CTX 0x8
-#define I810_UPLOAD_BUFFERS 0x10
-#define I810_REFRESH_RING 0x20
-#define I810_EMIT_CLIPRECT 0x40
-
typedef void (*i810_interp_func)( GLfloat t,
GLfloat *result,
@@ -88,7 +85,6 @@ struct i810_context_t {
*/
GLuint Setup[I810_CTX_SETUP_SIZE];
GLuint BufferSetup[I810_DEST_SETUP_SIZE];
- GLuint ClipSetup[I810_CLIP_SETUP_SIZE];
/* Support for CVA and the fast paths.
@@ -125,24 +121,38 @@ struct i810_context_t {
/* DRI stuff
*/
+ drmBufPtr vertex_dma_buffer;
+ GLuint vertex_prim;
+
GLframebuffer *glBuffer;
+ /* Two flags to keep track of fallbacks.
+ */
+ GLuint IndirectTriangles;
GLuint Fallback;
+
+
GLuint needClip;
/* These refer to the current draw (front vs. back) buffer:
*/
- int drawOffset; /* draw buffer address in agp space */
+ char *drawMap; /* draw buffer address in virtual mem */
+ char *readMap;
int drawX; /* origin of drawable in draw buffer */
int drawY;
GLuint numClipRects; /* cliprects for that buffer */
XF86DRIClipRectPtr pClipRects;
-
int lastSwap;
+ int secondLastSwap;
int texAge;
+ int ctxAge;
+ int dirtyAge;
+ int any_contend; /* throttle me harder */
- XF86DRIClipRectRec draw_rect;
+ int scissor;
+ drm_clip_rect_t draw_rect;
+ drm_clip_rect_t scissor_rect;
drmContext hHWContext;
drmLock *driHwLock;
@@ -152,7 +162,7 @@ struct i810_context_t {
__DRIdrawablePrivate *driDrawable;
__DRIscreenPrivate *driScreen;
i810ScreenPrivate *i810Screen;
- I810SAREAPriv *sarea;
+ drm_i810_sarea_t *sarea;
};
@@ -161,7 +171,7 @@ struct i810_context_t {
*/
#define I810_DEBUG 0
#ifndef I810_DEBUG
-/* #warning "Debugging enabled - expect reduced performance" */
+#warning "Debugging enabled - expect reduced performance"
extern int I810_DEBUG;
#endif
@@ -176,6 +186,7 @@ extern int I810_DEBUG;
#define DEBUG_VALIDATE_RING 0x800
#define DEBUG_VERBOSE_LRU 0x1000
#define DEBUG_VERBOSE_DRI 0x2000
+#define DEBUG_VERBOSE_IOCTL 0x4000
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dd.c b/xc/lib/GL/mesa/src/drv/i810/i810dd.c
index c1fbda734..583eb630c 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810dd.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810dd.c
@@ -29,8 +29,6 @@
#include <stdio.h>
#include "mm.h"
-#include "i810lib.h"
-#include "i810clear.h"
#include "i810dd.h"
#include "i810log.h"
#include "i810state.h"
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810dma.h b/xc/lib/GL/mesa/src/drv/i810/i810dma.h
deleted file mode 100644
index 9d472719a..000000000
--- a/xc/lib/GL/mesa/src/drv/i810/i810dma.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- GLX Hardware Device Driver for Intel i810
- Copyright (C) 1999 Keith Whitwell <keithw@precisioninsight.com>
-
- This program 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
- any later version.
-
- This program 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 this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- original by Jeff Hartmann <slicer@ionet.net>
- 6/16/99: rewrite by John Carmack <johnc@idsoftware.com>
- Oct 99: port to i180 by Keith Whitwell <keithw@precisioninsight.com>
-*/
-
-#ifndef I810DMA_H
-#define I810DMA_H
-
-#include "i810lib.h"
-#include "mm.h"
-
-/* a flush command will guarantee that all data added to the dma buffer
-is on its way to the card, and will eventually complete with no more
-intervention.
-*/
-void i810DmaFlush( i810ContextPtr imesa );
-
-/* the overflow function is called when a block can't be allocated
-in the current dma buffer. It flushes the current buffer and
-records some information */
-void i810DmaOverflow(int newDwords);
-
-/* a finish command will guarantee that all dma commands have actually
-been consumed by the card. Note that there may still be a couple primitives
-that have not yet been executed out of the internal FIFO, so this does not
-guarantee that the drawing engine is idle. */
-void i810DmaFinish( i810ContextPtr imesa );
-
-
-
-typedef struct {
- unsigned long Start;
- unsigned long End;
- unsigned long Size;
-} I810MemRange;
-
-
-
-typedef struct i810_batch_buffer {
- I810MemRange mem;
- char *virtual_start;
- int head;
- int space;
- int additional_space;
- int texture_age;
-} i810BatchBuffer;
-
-
-
-#define I810_USE_BATCH 0
-#if I810_USE_BATCH
-
-#define BEGIN_BATCH( imesa, n ) \
- unsigned int outbatch; \
- volatile char *virt; \
- if (I810_DEBUG & DEBUG_VERBOSE_RING) \
- fprintf(stderr, \
- "BEGIN_BATCH(%d) in %s\n" \
- "(spc left %d/%ld, head %x vstart %p start %lx)\n", \
- n, __FUNCTION__, i810glx.dma_buffer->space, \
- i810glx.dma_buffer->mem.Size - i810glx.dma_buffer->head, \
- i810glx.dma_buffer->head, \
- i810glx.dma_buffer->virtual_start, \
- i810glx.dma_buffer->mem.Start ); \
- if (i810glx.dma_buffer->space < n*4) \
- i810DmaOverflow(n); \
- outbatch = i810glx.dma_buffer->head; \
- virt = i810glx.dma_buffer->virtual_start;
-
-
-#define OUT_BATCH(val) { \
- *(volatile unsigned int *)(virt + outbatch) = val; \
- if (I810_DEBUG & DEBUG_VERBOSE_RING) \
- fprintf(stderr, "OUT_BATCH %x: %x\n", (int)(outbatch/4), (int)(val)); \
- outbatch += 4; \
-}
-
-
-#define ADVANCE_BATCH() { \
- if (I810_DEBUG & DEBUG_VERBOSE_RING) \
- fprintf(stderr, "ADVANCE_BATCH(%f) in %s\n", \
- (outbatch - i810glx.dma_buffer->head) / 4.0, \
- __FUNCTION__); \
- i810glx.dma_buffer->space -= outbatch - i810glx.dma_buffer->head; \
- i810glx.dma_buffer->head = outbatch; \
-}
-
-#define FINISH_PRIM()
-
-#else
-
-
-/* As an alternate path to dma, we can export the registers (and hence
- * ringbuffer) to the client. For security we should alloc these
- * things in agp memory which isn't exported to the client. But then
- * again, the client could blit over such things if it wanted to hang
- * the system.
- *
- * Malicious clients aren't really delt with by the DRI.
- */
-
-
-extern void _I810RefreshLpRing( i810ContextPtr imesa, int update );
-extern int _I810WaitLpRing( i810ContextPtr imesa, int n, int timeout_usec );
-extern int _I810Sync( i810ContextPtr imesa );
-
-
-#define OUT_RING(n) { \
- if (I810_DEBUG & DEBUG_VERBOSE_RING) \
- fprintf(stderr, "OUT_RING %x: %x\n", outring, (int)(n)); \
- if (!(I810_DEBUG & DEBUG_NO_OUTRING)) { \
- *(volatile unsigned int *)(virt + outring) = n; \
- outring += 4; \
- outring &= ringmask; \
- } \
-}
-
-#define ADVANCE_LP_RING() { \
- i810glx.LpRing.tail = outring; \
- OUTREG(LP_RING + RING_TAIL, outring); \
-}
-
-#define BEGIN_LP_RING(imesa, n) \
- unsigned int outring, ringmask; \
- volatile char *virt; \
- if ((I810_DEBUG&DEBUG_ALWAYS_SYNC) && n>2) _I810Sync( imesa ); \
- if (i810glx.LpRing.space < n*4) _I810WaitLpRing( imesa, n*4, 0); \
- i810glx.LpRing.space -= n*4; \
- if (I810_DEBUG & DEBUG_VERBOSE_RING) \
- fprintf(stderr, "BEGIN_LP_RING %d in %s\n", n, __FUNCTION__); \
- if (I810_DEBUG & DEBUG_VALIDATE_RING) { \
- CARD32 tail = INREG(LP_RING+RING_TAIL); \
- if (tail != i810glx.LpRing.tail) { \
- fprintf(stderr, "tail %x pI810->LpRing.tail %x\n", \
- (int) tail, (int) i810glx.LpRing.tail); \
- exit(1); \
- } \
- } \
- i810glx.LpRing.synced = 0; \
- outring = i810glx.LpRing.tail; \
- ringmask = i810glx.LpRing.tail_mask; \
- virt = i810glx.LpRing.virtual_start;
-
-
-#define EXTRAAA \
-
-#define INREG(addr) *(volatile CARD32 *)(i810glx.MMIOBase + (addr))
-#define INREG16(addr) *(volatile CARD16 *)(i810glx.MMIOBase + (addr))
-#define INREG8(addr) *(volatile CARD8 *)(i810glx.MMIOBase + (addr))
-
-#define OUTREG(addr, val) do { \
- if (I810_DEBUG&DEBUG_VERBOSE_OUTREG) \
- fprintf(stderr, "OUTREG(%x, %x)\n", addr, val); \
- if (!(I810_DEBUG&DEBUG_NO_OUTREG)) \
- *(volatile CARD32 *)(i810glx.MMIOBase + (addr)) = (val); \
-} while (0)
-
-
-#define BEGIN_BATCH(imesa, n) BEGIN_LP_RING(imesa, n)
-#define ADVANCE_BATCH() ADVANCE_LP_RING()
-#define OUT_BATCH(val) OUT_RING(val)
-#define FINISH_PRIM() OUTREG(LP_RING + RING_TAIL, i810glx.LpRing.tail)
-
-#endif
-
-
-
-#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c
new file mode 100644
index 000000000..b4e86cff2
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.c
@@ -0,0 +1,477 @@
+#include <stdio.h>
+#include <unistd.h>
+
+
+#include "types.h"
+#include "pb.h"
+#include "dd.h"
+
+#include "mm.h"
+#include "i810context.h"
+#include "i810log.h"
+#include "i810ioctl.h"
+
+#include "drm.h"
+#include <sys/ioctl.h>
+
+static drmBufPtr i810_get_buffer_ioctl( i810ContextPtr imesa )
+{
+ drm_i810_dma_t dma;
+ drmBufPtr buf;
+ int retcode;
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "Getting dma buffer\n");
+
+ while (1) {
+ retcode = ioctl(imesa->driFd, DRM_IOCTL_I810_GETBUF, &dma);
+
+ if (dma.granted == 1 && retcode == 0)
+ break;
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "Retcode : %d, granted : %d\n", retcode, dma.granted);
+
+ ioctl(imesa->driFd, DRM_IOCTL_I810_FLUSH);
+ }
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr,
+ "imesa->i810Screen->bufs->list : %p, "
+ "dma.request_idx : %d\n",
+ imesa->i810Screen->bufs->list, dma.request_idx);
+
+ buf = &(imesa->i810Screen->bufs->list[dma.request_idx]);
+ buf->idx = dma.request_idx;
+ buf->used = 0;
+ buf->total = dma.request_size;
+ buf->address = (drmAddress)dma.virtual;
+ return buf;
+}
+
+
+
+#define DEPTH_SCALE ((1<<16)-1)
+
+GLbitfield i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint cx, GLint cy, GLint cw, GLint ch )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
+ drm_i810_clear_t clear;
+ int i;
+
+ clear.flags = 0;
+ clear.clear_color = imesa->ClearColor;
+ clear.clear_depth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE);
+
+ FLUSH_BATCH( imesa );
+
+ if ((mask & DD_FRONT_LEFT_BIT) && colorMask == ~0) {
+ clear.flags |= I810_FRONT;
+ mask &= ~DD_FRONT_LEFT_BIT;
+ }
+
+ if ((mask & DD_BACK_LEFT_BIT) && colorMask == ~0) {
+ clear.flags |= I810_BACK;
+ mask &= ~DD_BACK_LEFT_BIT;
+ }
+
+ if ((mask & DD_DEPTH_BIT) && ctx->Depth.Mask) {
+ clear.flags |= I810_DEPTH;
+ mask &= ~DD_DEPTH_BIT;
+ }
+
+ if (!clear.flags)
+ return mask;
+
+ LOCK_HARDWARE( imesa );
+
+ /* flip top to bottom */
+ cy = dPriv->h-cy-ch;
+ cx += imesa->drawX;
+ cy += imesa->drawY;
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "Clear, bufs %x nbox %d\n",
+ (int)clear.flags, (int)imesa->numClipRects);
+
+ for (i = 0 ; i < imesa->numClipRects ; )
+ {
+ int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, imesa->numClipRects);
+ XF86DRIClipRectRec *box = imesa->pClipRects;
+ drm_clip_rect_t *b = imesa->sarea->boxes;
+ int n = 0;
+
+ if (!all) {
+ for ( ; i < nr ; i++) {
+ GLint x = box[i].x1;
+ GLint y = box[i].y1;
+ GLint w = box[i].x2 - x;
+ GLint h = box[i].y2 - y;
+
+ if (x < cx) w -= cx - x, x = cx;
+ if (y < cy) h -= cy - y, y = cy;
+ if (x + w > cx + cw) w = cx + cw - x;
+ if (y + h > cy + ch) h = cy + ch - y;
+ if (w <= 0) continue;
+ if (h <= 0) continue;
+
+ b->x1 = x;
+ b->y1 = y;
+ b->x2 = x + w;
+ b->y2 = y + h;
+ b++;
+ n++;
+ }
+ } else {
+ for ( ; i < nr ; i++) {
+ *b++ = *(drm_clip_rect_t *)&box[i];
+ n++;
+ }
+ }
+
+ imesa->sarea->nbox = n;
+ ioctl(imesa->driFd, DRM_IOCTL_I810_CLEAR, &clear);
+ }
+
+ UNLOCK_HARDWARE( imesa );
+ imesa->dirty |= I810_UPLOAD_CLIPRECTS;
+
+ return mask;
+}
+
+
+
+
+/*
+ * Copy the back buffer to the front buffer.
+ */
+void i810SwapBuffers( i810ContextPtr imesa )
+{
+ __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+ XF86DRIClipRectPtr pbox;
+ int nbox;
+ int i;
+ int tmp;
+
+ FLUSH_BATCH( imesa );
+ LOCK_HARDWARE( imesa );
+
+ pbox = dPriv->pClipRects;
+ nbox = dPriv->numClipRects;
+
+ for (i = 0 ; i < nbox ; )
+ {
+ int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
+ XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)imesa->sarea->boxes;
+
+ imesa->sarea->nbox = nr - i;
+
+ for ( ; i < nr ; i++)
+ *b++ = pbox[i];
+
+ ioctl(imesa->driFd, DRM_IOCTL_I810_SWAP);
+ }
+
+ tmp = GET_ENQUEUE_AGE(imesa);
+ UNLOCK_HARDWARE( imesa );
+
+ if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap)
+ i810WaitAge(imesa, imesa->lastSwap);
+
+ imesa->lastSwap = tmp;
+ imesa->dirty |= I810_UPLOAD_CLIPRECTS;
+}
+
+
+
+
+
+
+/* This waits for *everybody* to finish rendering -- overkill.
+ */
+void i810DmaFinish( i810ContextPtr imesa )
+{
+ FLUSH_BATCH( imesa );
+
+ if (imesa->sarea->last_quiescent != imesa->sarea->last_enqueue) {
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "i810DmaFinish\n");
+
+ LOCK_HARDWARE( imesa );
+ i810RegetLockQuiescent( imesa );
+ UNLOCK_HARDWARE( imesa );
+ imesa->sarea->last_quiescent = imesa->sarea->last_enqueue;
+ }
+}
+
+
+void i810RegetLockQuiescent( i810ContextPtr imesa )
+{
+ if (imesa->sarea->last_quiescent != imesa->sarea->last_enqueue) {
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "i810RegetLockQuiescent\n");
+
+ drmUnlock(imesa->driFd, imesa->hHWContext);
+ i810GetLock( imesa, DRM_LOCK_QUIESCENT );
+ imesa->sarea->last_quiescent = imesa->sarea->last_enqueue;
+ }
+}
+
+void i810WaitAgeLocked( i810ContextPtr imesa, int age )
+{
+ int i = 0;
+
+
+ while (++i < 500000 && GET_DISPATCH_AGE(imesa) < age) {
+ ioctl(imesa->driFd, DRM_IOCTL_I810_GETAGE);
+ }
+
+ if (GET_DISPATCH_AGE(imesa) < age) {
+ if (0)
+ fprintf(stderr, "wait locked %d %d\n", age, GET_DISPATCH_AGE(imesa));
+ ioctl(imesa->driFd, DRM_IOCTL_I810_FLUSH);
+ }
+}
+
+
+void i810WaitAge( i810ContextPtr imesa, int age )
+{
+ int i = 0;
+
+ while (++i < 500000 && GET_DISPATCH_AGE(imesa) < age) {
+ ioctl(imesa->driFd, DRM_IOCTL_I810_GETAGE);
+ }
+
+ if (GET_DISPATCH_AGE(imesa) >= age)
+ return;
+
+ i = 0;
+ while (++i < 1000 && GET_DISPATCH_AGE(imesa) < age) {
+ ioctl(imesa->driFd, DRM_IOCTL_I810_GETAGE);
+ usleep(1000);
+ }
+
+ /* To be effective at letting other clients at the hardware,
+ * particularly the X server which regularly needs quiescence to
+ * touch the framebuffer, we really need to sleep *beyond* the
+ * point where our last buffer clears the hardware.
+ */
+ if (imesa->any_contend) {
+ usleep(3000);
+ }
+
+ imesa->any_contend = 0;
+
+ if (GET_DISPATCH_AGE(imesa) < age) {
+ LOCK_HARDWARE(imesa);
+ if (GET_DISPATCH_AGE(imesa) < age)
+ ioctl(imesa->driFd, DRM_IOCTL_I810_FLUSH);
+ UNLOCK_HARDWARE(imesa);
+ }
+}
+
+
+
+void i810FlushVertices( i810ContextPtr imesa )
+{
+ if (!imesa->vertex_dma_buffer) return;
+
+ LOCK_HARDWARE( imesa );
+ i810FlushVerticesLocked( imesa );
+ UNLOCK_HARDWARE( imesa );
+}
+
+
+static int intersect_rect( drm_clip_rect_t *out,
+ drm_clip_rect_t *a,
+ drm_clip_rect_t *b )
+{
+ *out = *a;
+ if (b->x1 > out->x1) out->x1 = b->x1;
+ if (b->y1 > out->y1) out->y1 = b->y1;
+ if (b->x2 < out->x2) out->x2 = b->x2;
+ if (b->y2 < out->y2) out->y2 = b->y2;
+ if (out->x1 >= out->x2) return 0;
+ if (out->y1 >= out->y2) return 0;
+ return 1;
+}
+
+
+static void age_imesa( i810ContextPtr imesa, int age )
+{
+ if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->age = age;
+ if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->age = age;
+}
+
+void i810FlushVerticesLocked( i810ContextPtr imesa )
+{
+ drm_clip_rect_t *pbox = (drm_clip_rect_t *)imesa->pClipRects;
+ int nbox = imesa->numClipRects;
+ drmBufPtr buffer = imesa->vertex_dma_buffer;
+ drm_i810_vertex_t vertex;
+ int i;
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "i810FlushVerticesLocked, buf->used %d\n",
+ buffer->used);
+
+ if (!buffer)
+ return;
+
+ if (imesa->dirty & ~I810_UPLOAD_CLIPRECTS)
+ i810EmitHwStateLocked( imesa );
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "i810FlushVerticesLocked, used %d\n",
+ buffer->used);
+
+ imesa->vertex_dma_buffer = 0;
+
+ vertex.idx = buffer->idx;
+ vertex.used = buffer->used;
+ vertex.discard = 0;
+
+ if (!nbox)
+ vertex.used = 0;
+
+ if (nbox > I810_NR_SAREA_CLIPRECTS)
+ imesa->dirty |= I810_UPLOAD_CLIPRECTS;
+
+ imesa->sarea->vertex_prim = imesa->vertex_prim;
+
+ if (!nbox || !(imesa->dirty & I810_UPLOAD_CLIPRECTS))
+ {
+ if (nbox == 1)
+ imesa->sarea->nbox = 0;
+ else
+ imesa->sarea->nbox = nbox;
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "DRM_IOCTL_I810_VERTEX CASE1 nbox %d used %d\n",
+ nbox, vertex.used);
+
+ vertex.discard = 1;
+ ioctl(imesa->driFd, DRM_IOCTL_I810_VERTEX, &vertex);
+ age_imesa(imesa, imesa->sarea->last_enqueue);
+ }
+ else
+ {
+ for (i = 0 ; i < nbox ; )
+ {
+ int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, nbox);
+ drm_clip_rect_t *b = imesa->sarea->boxes;
+
+ if (imesa->scissor) {
+ imesa->sarea->nbox = 0;
+
+ for ( ; i < nr ; i++) {
+ b->x1 = pbox[i].x1 - imesa->drawX;
+ b->y1 = pbox[i].y1 - imesa->drawY;
+ b->x2 = pbox[i].x2 - imesa->drawX;
+ b->y2 = pbox[i].y2 - imesa->drawY;
+
+ if (intersect_rect(b, b, &imesa->scissor_rect)) {
+ imesa->sarea->nbox++;
+ b++;
+ }
+ }
+
+ /* Culled?
+ */
+ if (!imesa->sarea->nbox) {
+ if (nr < nbox) continue;
+ vertex.used = 0;
+ }
+ } else {
+ imesa->sarea->nbox = nr - i;
+ for ( ; i < nr ; i++, b++) {
+ b->x1 = pbox[i].x1 - imesa->drawX;
+ b->y1 = pbox[i].y1 - imesa->drawY;
+ b->x2 = pbox[i].x2 - imesa->drawX;
+ b->y2 = pbox[i].y2 - imesa->drawY;
+ }
+ }
+
+ /* Finished with the buffer?
+ */
+ if (nr == nbox)
+ vertex.discard = 1;
+
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "DRM_IOCTL_I810_VERTEX nbox %d used %d\n",
+ nbox, vertex.used);
+
+ ioctl(imesa->driFd, DRM_IOCTL_I810_VERTEX, &vertex);
+ age_imesa(imesa, imesa->sarea->last_enqueue);
+ }
+ }
+
+ imesa->dirty = 0;
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "finished i810FlushVerticesLocked\n");
+}
+
+
+GLuint *i810AllocDwords( i810ContextPtr imesa, int dwords, GLuint prim )
+{
+ GLuint *start;
+
+ if (!imesa->vertex_dma_buffer)
+ {
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "i810AllocPrimitiveVerts -- get buf\n");
+ LOCK_HARDWARE(imesa);
+ imesa->vertex_dma_buffer = i810_get_buffer_ioctl( imesa );
+ imesa->vertex_dma_buffer->used = 4;
+ imesa->vertex_prim = prim;
+ UNLOCK_HARDWARE(imesa);
+ }
+ else if (imesa->vertex_prim != prim ||
+ imesa->vertex_dma_buffer->used + dwords * 4 >
+ imesa->vertex_dma_buffer->total)
+ {
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "i810AllocPrimitiveVerts -- flush\n");
+ i810FlushVertices( imesa );
+ LOCK_HARDWARE(imesa);
+ imesa->vertex_dma_buffer = i810_get_buffer_ioctl( imesa );
+ imesa->vertex_dma_buffer->used = 4;
+ imesa->vertex_prim = prim;
+ UNLOCK_HARDWARE(imesa);
+ }
+
+
+ if (0)
+ fprintf(stderr, "i810AllocPrimitiveVerts %d, buf %d, used %d\n",
+ dwords, imesa->vertex_dma_buffer->idx,
+ imesa->vertex_dma_buffer->used);
+
+ start = (GLuint *)((char *)imesa->vertex_dma_buffer->address +
+ imesa->vertex_dma_buffer->used);
+
+ imesa->vertex_dma_buffer->used += dwords * 4;
+
+ return start;
+}
+
+static void i810DDFlush( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ FLUSH_BATCH( imesa );
+}
+
+static void i810DDFinish( GLcontext *ctx )
+{
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ i810DmaFinish( imesa );
+}
+
+void i810DDInitIoctlFuncs( GLcontext *ctx )
+{
+ ctx->Driver.Flush = i810DDFlush;
+ ctx->Driver.Finish = i810DDFinish;
+}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h
new file mode 100644
index 000000000..004b723b4
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/i810/i810ioctl.h
@@ -0,0 +1,36 @@
+#ifndef MGA_IOCTL_H
+#define MGA_IOCTL_H
+
+#include "i810context.h"
+
+
+GLuint *i810AllocDwords( i810ContextPtr imesa, int dwords, GLuint prim );
+
+void i810GetGeneralDmaBufferLocked( i810ContextPtr mmesa );
+
+void i810FlushVertices( i810ContextPtr mmesa );
+void i810FlushVerticesLocked( i810ContextPtr mmesa );
+
+void i810FlushGeneralLocked( i810ContextPtr imesa );
+void i810WaitAgeLocked( i810ContextPtr imesa, int age );
+void i810WaitAge( i810ContextPtr imesa, int age );
+
+void i810DmaFinish( i810ContextPtr imesa );
+
+void i810RegetLockQuiescent( i810ContextPtr imesa );
+
+void i810DDInitIoctlFuncs( GLcontext *ctx );
+
+void i810SwapBuffers( i810ContextPtr imesa );
+
+GLbitfield i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint cx, GLint cy, GLint cw, GLint ch );
+
+#define FLUSH_BATCH(imesa) do { \
+ if (I810_DEBUG&DEBUG_VERBOSE_IOCTL) \
+ fprintf(stderr, "FLUSH_BATCH in %s\n", __FUNCTION__); \
+ if (imesa->vertex_dma_buffer) i810FlushVertices(imesa); \
+} while (0)
+
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810lib.h b/xc/lib/GL/mesa/src/drv/i810/i810lib.h
deleted file mode 100644
index ad80674f0..000000000
--- a/xc/lib/GL/mesa/src/drv/i810/i810lib.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * GLX Hardware Device Driver for Intel i810
- * Copyright (C) 1999 Keith Whitwell
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- *
- */
-
-#ifndef I810LIB_INC
-#define I810LIB_INC
-
-#include <stdio.h>
-
-#include "i810context.h"
-#include "mm.h"
-#include "i810log.h"
-
-
-struct i810_mem_range {
- unsigned long Start;
- unsigned long End;
- unsigned long Size;
-};
-
-struct i810_batch_buffer;
-
-struct i810_ring_buffer {
- int tail_mask;
- struct i810_mem_range mem;
- char *virtual_start;
- int head;
- int tail;
- int space;
- int synced;
-};
-
-typedef struct {
- /* logging stuff */
- GLuint logLevel;
- FILE *logFile;
-
- /* bookkeeping for texture swaps */
- GLuint dma_buffer_age;
- GLuint current_texture_age;
-
- /* options */
- GLuint nullprims; /* skip all primitive generation */
- GLuint boxes; /* draw performance boxes */
- GLuint noFallback; /* don't fall back to software */
- GLuint skipDma; /* don't send anything to hardware */
-
- /* performance counters */
- GLuint c_setupPointers;
- GLuint c_triangles;
- GLuint c_points;
- GLuint c_lines;
- GLuint c_drawWaits;
- GLuint c_textureSwaps;
- GLuint c_dmaFlush;
- GLuint c_overflows;
-
- GLuint c_ringlost;
- GLuint c_texlost;
- GLuint c_ctxlost;
-
- GLuint hardwareWentIdle; /* cleared each swapbuffers, set if a
- waitfordmacompletion ever exited
- without having to wait */
-
- unsigned char *texVirtual;
-
-
- struct i810_batch_buffer *dma_buffer;
- struct i810_ring_buffer LpRing;
- unsigned char *MMIOBase;
-
-} i810Glx_t;
-
-extern i810Glx_t i810glx;
-
-
-#define I810PACKCOLOR1555(r,g,b,a) \
- ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
- ((a) ? 0x8000 : 0))
-
-#define I810PACKCOLOR565(r,g,b) \
- ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
-
-#define I810PACKCOLOR4444(r,g,b,a) \
- ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
-
-
-#include "i810_3d_reg.h"
-
-static __inline__ GLuint i810PackColor(GLuint format,
- GLubyte r, GLubyte g,
- GLubyte b, GLubyte a)
-{
- switch (format) {
- case DV_PF_555:
- return I810PACKCOLOR1555(r,g,b,a);
- case DV_PF_565:
- return I810PACKCOLOR565(r,g,b);
- default:
- fprintf(stderr, "unknown format %d\n", (int)format);
- return 0;
- }
-}
-
-
-
-
-#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c
index fb2d368fe..34171d943 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810pipeline.c
@@ -1,13 +1,15 @@
/* #include "i810pipeline.h" */
#include <stdio.h>
+
+#include "types.h"
+#include "fog.h"
+
#include "i810vb.h"
#include "i810dd.h"
-#include "i810lib.h"
#include "i810tris.h"
#include "i810pipeline.h"
-#include "fog.h"
static struct gl_pipeline_stage i810_fast_stage = {
"I810 fast path",
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810span.c b/xc/lib/GL/mesa/src/drv/i810/i810span.c
index 20c463b9b..aa4f22d0c 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810span.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810span.c
@@ -1,7 +1,5 @@
#include "types.h"
#include "i810dd.h"
-#include "i810lib.h"
-#include "i810dma.h"
#include "i810log.h"
#include "i810span.h"
#include "i810ioctl.h"
@@ -127,7 +125,7 @@ do { \
/* 16 bit depthbuffer functions.
*/
#define WRITE_DEPTH( _x, _y, d ) \
- *(GLushort *)(buf + _x*2 + _y*pitch) = d;
+ *(GLushort *)(buf + _x*2 + _y*pitch) = d;
#define READ_DEPTH( d, _x, _y ) \
d = *(GLushort *)(buf + _x*2 + _y*pitch);
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810state.c b/xc/lib/GL/mesa/src/drv/i810/i810state.c
index bc3391e42..80332e3b3 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810state.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810state.c
@@ -7,24 +7,40 @@
#include "dd.h"
#include "mm.h"
-#include "i810lib.h"
#include "i810dd.h"
#include "i810context.h"
#include "i810state.h"
-#include "i810depth.h"
#include "i810tex.h"
#include "i810log.h"
#include "i810vb.h"
#include "i810tris.h"
+#include "i810ioctl.h"
+
+
+static __inline__ GLuint i810PackColor(GLuint format,
+ GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a)
+{
+ switch (format) {
+ case DV_PF_555:
+ return I810PACKCOLOR1555(r,g,b,a);
+ case DV_PF_565:
+ return I810PACKCOLOR565(r,g,b);
+ default:
+ fprintf(stderr, "unknown format %d\n", (int)format);
+ return 0;
+ }
+}
static void i810DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref)
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
-
CARD32 a = (ZA_UPDATE_ALPHAFUNC|ZA_UPDATE_ALPHAREF);
+ FLUSH_BATCH(imesa);
+
switch (ctx->Color.AlphaFunc) {
case GL_NEVER: a |= ZA_ALPHA_NEVER; break;
case GL_LESS: a |= ZA_ALPHA_LESS; break;
@@ -44,10 +60,6 @@ static void i810DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref)
imesa->Setup[I810_CTXREG_ZA] |= a;
}
-/* This shouldn't get called, as the extension is disabled. However,
- * there are internal Mesa calls, and rogue use of the api which must be
- * caught.
- */
static void i810DDBlendEquation(GLcontext *ctx, GLenum mode)
{
if (mode != GL_FUNC_ADD_EXT) {
@@ -60,9 +72,8 @@ static void i810DDBlendEquation(GLcontext *ctx, GLenum mode)
static void i810DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
- GLuint a;
-
- a = SDM_UPDATE_SRC_BLEND | SDM_UPDATE_DST_BLEND;
+ GLuint a = SDM_UPDATE_SRC_BLEND | SDM_UPDATE_DST_BLEND;
+ FLUSH_BATCH(imesa);
switch (ctx->Color.BlendSrcRGB) {
case GL_ZERO: a |= SDM_SRC_ZERO; break;
@@ -73,13 +84,8 @@ static void i810DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_SRC_INV_SRC_ALPHA; break;
case GL_DST_ALPHA: a |= SDM_SRC_ONE; break;
case GL_ONE_MINUS_DST_ALPHA: a |= SDM_SRC_ZERO; break;
- case GL_SRC_ALPHA_SATURATE:
- a |= SDM_SRC_SRC_ALPHA; /* use GFXRENDERSTATE_COLOR_FACTOR ??? */
- break;
- default:
- i810Error("unknown blend source func");
- exit(1);
- return;
+ case GL_SRC_ALPHA_SATURATE: a |= SDM_SRC_SRC_ALPHA; break;
+ default: return;
}
switch (ctx->Color.BlendDstRGB) {
@@ -91,10 +97,7 @@ static void i810DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
case GL_ONE_MINUS_SRC_COLOR: a |= SDM_DST_INV_SRC_COLOR; break;
case GL_DST_ALPHA: a |= SDM_DST_ONE; break;
case GL_ONE_MINUS_DST_ALPHA: a |= SDM_DST_ZERO; break;
- default:
- i810Error( "unknown blend dst func");
- exit(1);
- return;
+ default: return;
}
imesa->dirty |= I810_UPLOAD_CTX;
@@ -123,6 +126,8 @@ static void i810DDDepthFunc(GLcontext *ctx, GLenum func)
i810ContextPtr imesa = I810_CONTEXT(ctx);
int zmode;
+ FLUSH_BATCH(imesa);
+
switch(func) {
case GL_NEVER: zmode = LCS_Z_NEVER; break;
case GL_ALWAYS: zmode = LCS_Z_ALWAYS; break;
@@ -134,9 +139,9 @@ static void i810DDDepthFunc(GLcontext *ctx, GLenum func)
case GL_NOTEQUAL: zmode = LCS_Z_NOTEQUAL; break;
default: return;
}
-
+
imesa->Setup[I810_CTXREG_LCS] &= ~LCS_Z_MASK;
- imesa->Setup[I810_CTXREG_LCS] |= LCS_UPDATE_ZMODE | zmode;
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_UPDATE_ZMODE | zmode;
imesa->dirty |= I810_UPLOAD_CTX;
}
@@ -144,20 +149,62 @@ static void i810DDDepthMask(GLcontext *ctx, GLboolean flag)
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
+ FLUSH_BATCH(imesa);
+
imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_B2] &= ~B2_ZB_WRITE_ENABLE;
- imesa->Setup[I810_CTXREG_B2] |= B2_UPDATE_ZB_WRITE_ENABLE;
if (flag)
imesa->Setup[I810_CTXREG_B2] |= B2_ZB_WRITE_ENABLE;
}
+/* =============================================================
+ * Polygon stipple
+ *
+ * The i810 supports a 4x4 stipple natively, GL wants 32x32.
+ * Fortunately stipple is usually a repeating pattern. Could
+ * also consider using a multitexturing mechanism for this, but
+ * that has real issues, too.
+ */
+static void i810DDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ const GLubyte *m = mask;
+ GLubyte p[4];
+ int i,j,k;
+ int active = (ctx->Polygon.StippleFlag && ctx->PB->primitive == GL_POLYGON);
+ FLUSH_BATCH(imesa);
+ ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE;
+ if (active) {
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE;
+ }
-
-
+ p[0] = mask[0] & 0xf; p[0] |= p[0] << 4;
+ p[1] = mask[4] & 0xf; p[1] |= p[1] << 4;
+ p[2] = mask[8] & 0xf; p[2] |= p[2] << 4;
+ p[3] = mask[12] & 0xf; p[3] |= p[3] << 4;
+
+ for (k = 0 ; k < 8 ; k++)
+ for (j = 0 ; j < 4; j++)
+ for (i = 0 ; i < 4 ; i++)
+ if (*m++ != p[j]) {
+ ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE;
+ return;
+ }
+
+ imesa->Setup[I810_CTXREG_ST1] &= ~0xffff;
+ imesa->Setup[I810_CTXREG_ST1] |= ( ((p[0] & 0xf) << 0) |
+ ((p[1] & 0xf) << 4) |
+ ((p[2] & 0xf) << 8) |
+ ((p[3] & 0xf) << 12) );
+
+ if (active)
+ imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE;
+}
@@ -167,40 +214,26 @@ static void i810DDDepthMask(GLcontext *ctx, GLboolean flag)
static void i810DDScissor( GLcontext *ctx, GLint x, GLint y,
- GLsizei w, GLsizei h )
+ GLsizei w, GLsizei h )
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
- __DRIdrawablePrivate *dPriv = imesa->driDrawable;
- int x1,x2,y1,y2;
- x1 = ctx->Scissor.X;
- x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
- y1 = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height;
- y2 = dPriv->h - ctx->Scissor.Y - 1;
-
- if (x1 < 0) x1 = 0;
- if (y1 < 0) y1 = 0;
- if (x2 >= dPriv->w) x2 = dPriv->w-1;
- if (y2 >= dPriv->h) y2 = dPriv->h-1;
-
- if (x1 > x2 || y1 > y2) {
- x1 = 0; x2 = 0;
- y2 = 0; y1 = 1;
- }
+ FLUSH_BATCH(imesa);
+ imesa->scissor_rect.x1 = x;
+ imesa->scissor_rect.y1 = imesa->driDrawable->h - (y+h);
+ imesa->scissor_rect.x2 = x+w;
+ imesa->scissor_rect.y2 = imesa->driDrawable->h - y;
- /* Need to push this into drawing rectangle.
- */
-#if 0
- imesa->Setup[I810_CTXREG_SCI0] = GFX_OP_SCISSOR_INFO;
- imesa->Setup[I810_CTXREG_SCI1] = (y1<<16)|x1;
- imesa->Setup[I810_CTXREG_SCI2] = (y2<<16)|x2;
+ if (I810_DEBUG&DEBUG_VERBOSE_2D)
+ fprintf(stderr, "SET SCISSOR %d,%d-%d,%d\n",
+ imesa->scissor_rect.x1,
+ imesa->scissor_rect.y1,
+ imesa->scissor_rect.x2,
+ imesa->scissor_rect.y2);
- /* Need to intersect with cliprects???
- */
- imesa->dirty |= I810_UPLOAD_CTX;
-#endif
+ imesa->dirty |= I810_UPLOAD_CLIPRECTS;
}
@@ -209,38 +242,56 @@ static void i810DDDither(GLcontext *ctx, GLboolean enable)
}
-static GLboolean i810DDSetBuffer(GLcontext *ctx, GLenum mode )
+static GLboolean i810DDSetDrawBuffer(GLcontext *ctx, GLenum mode )
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
+ FLUSH_BATCH(imesa);
- fprintf(stderr, "i810DDSetBuffer %s\n", gl_lookup_enum_by_nr( mode ));
-
- imesa->Fallback &= ~I810_FALLBACK_BUFFER;
+ imesa->Fallback &= ~I810_FALLBACK_DRAW_BUFFER;
if (mode == GL_FRONT_LEFT)
{
- imesa->drawOffset = imesa->i810Screen->fbOffset;
+ imesa->drawMap = imesa->driScreen->pFB;
imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->fbOffset |
- imesa->i810Screen->auxPitchBits);
+ imesa->i810Screen->backPitchBits);
imesa->dirty |= I810_UPLOAD_BUFFERS;
i810XMesaSetFrontClipRects( imesa );
return GL_TRUE;
}
else if (mode == GL_BACK_LEFT)
{
- imesa->drawOffset = imesa->i810Screen->backOffset;
+ imesa->drawMap = imesa->i810Screen->back.map;
imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->backOffset |
- imesa->i810Screen->auxPitchBits);
+ imesa->i810Screen->backPitchBits);
imesa->dirty |= I810_UPLOAD_BUFFERS;
i810XMesaSetBackClipRects( imesa );
return GL_TRUE;
}
- imesa->Fallback |= I810_FALLBACK_BUFFER;
+ imesa->Fallback |= I810_FALLBACK_DRAW_BUFFER;
return GL_FALSE;
}
+static void i810DDSetReadBuffer(GLcontext *ctx, GLframebuffer *colorBuffer,
+ GLenum mode )
+{
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+
+ if (mode == GL_FRONT_LEFT)
+ {
+ imesa->readMap = imesa->driScreen->pFB;
+ imesa->Fallback &= ~I810_FALLBACK_READ_BUFFER;
+ }
+ else if (mode == GL_BACK_LEFT)
+ {
+ imesa->readMap = imesa->i810Screen->back.map;
+ imesa->Fallback &= ~I810_FALLBACK_READ_BUFFER;
+ }
+ else
+ imesa->Fallback |= I810_FALLBACK_READ_BUFFER;
+}
+
static void i810DDSetColor(GLcontext *ctx,
@@ -248,9 +299,7 @@ static void i810DDSetColor(GLcontext *ctx,
GLubyte b, GLubyte a )
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
-
- imesa->MonoColor = i810PackColor( imesa->i810Screen->fbFormat,
- r, g, b, a );
+ imesa->MonoColor = i810PackColor( imesa->i810Screen->fbFormat, r, g, b, a );
}
@@ -259,9 +308,7 @@ static void i810DDClearColor(GLcontext *ctx,
GLubyte b, GLubyte a )
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
-
- imesa->ClearColor = i810PackColor( imesa->i810Screen->fbFormat,
- r, g, b, a );
+ imesa->ClearColor = i810PackColor( imesa->i810Screen->fbFormat, r, g, b, a );
}
@@ -274,6 +321,8 @@ static void i810DDCullFaceFrontFace(GLcontext *ctx, GLenum unused)
i810ContextPtr imesa = I810_CONTEXT(ctx);
GLuint mode = LCS_CULL_BOTH;
+ FLUSH_BATCH(imesa);
+
if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {
mode = LCS_CULL_CW;
if (ctx->Polygon.CullFaceMode == GL_FRONT)
@@ -288,27 +337,49 @@ static void i810DDCullFaceFrontFace(GLcontext *ctx, GLenum unused)
{
imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
- imesa->Setup[I810_CTXREG_LCS] |= (LCS_UPDATE_CULL_MODE | mode);
+ imesa->Setup[I810_CTXREG_LCS] |= mode;
}
}
static void i810DDReducedPrimitiveChange( GLcontext *ctx, GLenum prim )
{
- if (ctx->Polygon.CullFlag) {
- i810ContextPtr imesa = I810_CONTEXT(ctx);
- GLuint mode = imesa->LcsCullMode;
-
- if (ctx->PB->primitive != GL_POLYGON)
- mode = LCS_CULL_DISABLE;
-
- imesa->dirty |= I810_UPLOAD_CTX;
- imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
- imesa->Setup[I810_CTXREG_LCS] |= (LCS_UPDATE_CULL_MODE | mode);
+ i810ContextPtr imesa = I810_CONTEXT(ctx);
+ FLUSH_BATCH(imesa);
- LOCK_HARDWARE(imesa);
- i810EmitHwStateLocked( imesa );
- UNLOCK_HARDWARE(imesa);
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
+ imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE;
+ imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
+
+ switch (ctx->PB->primitive) {
+ case GL_POLYGON:
+ if (ctx->Polygon.StippleFlag &&
+ (ctx->Driver.TriangleCaps & DD_TRI_STIPPLE))
+ imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE;
+ if (ctx->Polygon.CullFlag)
+ imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsCullMode;
+ else
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE;
+ if (ctx->Polygon.SmoothFlag)
+ imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+ break;
+ case GL_LINES:
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5;
+ if (ctx->Line.SmoothFlag) {
+ imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_LINEWIDTH_0_5;
+ }
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE;
+ break;
+ case GL_POINTS:
+ if (ctx->Point.SmoothFlag)
+ imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE;
+ break;
+ default:
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE;
+ break;
}
}
@@ -318,15 +389,36 @@ static void i810DDReducedPrimitiveChange( GLcontext *ctx, GLenum prim )
* Color masks
*/
-/* Mesa calls this from the wrong place.
+/* Mesa calls this from the wrong place - it is called a very large
+ * number of redundant times.
*
- * Its a fallback...
+ * Colormask can be simulated by multipass or multitexture techniques.
*/
static GLboolean i810DDColorMask(GLcontext *ctx,
GLboolean r, GLboolean g,
GLboolean b, GLboolean a )
{
- return 1;
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ GLuint tmp = 0;
+ GLuint rv = 1;
+
+ imesa->Fallback &= ~I810_FALLBACK_COLORMASK;
+
+ if (r && g && b) {
+ tmp = imesa->Setup[I810_CTXREG_B2] | B2_FB_WRITE_ENABLE;
+ } else if (!r && !g && !b) {
+ tmp = imesa->Setup[I810_CTXREG_B2] & ~B2_FB_WRITE_ENABLE;
+ } else {
+ rv = 0;
+ imesa->Fallback |= I810_FALLBACK_COLORMASK;
+ }
+
+ if (tmp != imesa->Setup[I810_CTXREG_B2]) {
+ FLUSH_BATCH(imesa);
+ imesa->Setup[I810_CTXREG_B2] = tmp;
+ }
+
+ return rv;
}
/* Seperate specular not fully implemented in hardware... Needs
@@ -336,8 +428,14 @@ static GLboolean i810DDColorMask(GLcontext *ctx,
static void i810DDLightModelfv(GLcontext *ctx, GLenum pname,
const GLfloat *param)
{
- if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
- I810_CONTEXT(ctx)->new_state |= I810_NEW_TEXTURE;
+ if (pname == GL_LIGHT_MODEL_COLOR_CONTROL)
+ {
+ i810ContextPtr imesa = I810_CONTEXT( ctx );
+ FLUSH_BATCH(imesa);
+
+ imesa->Fallback &= ~I810_FALLBACK_SPECULAR;
+ if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
+ imesa->Fallback |= I810_FALLBACK_SPECULAR;
}
}
@@ -372,64 +470,105 @@ static void i810DDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
switch(cap) {
case GL_ALPHA_TEST:
+ FLUSH_BATCH(imesa);
imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_B1] &= ~B1_ALPHA_TEST_ENABLE;
- imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_ALPHA_TEST_ENABLE;
if (state)
imesa->Setup[I810_CTXREG_B1] |= B1_ALPHA_TEST_ENABLE;
break;
case GL_BLEND:
+ FLUSH_BATCH(imesa);
imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_B1] &= ~B1_BLEND_ENABLE;
- imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_BLEND_ENABLE;
if (state)
imesa->Setup[I810_CTXREG_B1] |= B1_BLEND_ENABLE;
break;
case GL_DEPTH_TEST:
+ FLUSH_BATCH(imesa);
imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_B1] &= ~B1_Z_TEST_ENABLE;
- imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_Z_TEST_ENABLE;
if (state)
imesa->Setup[I810_CTXREG_B1] |= B1_Z_TEST_ENABLE;
break;
case GL_SCISSOR_TEST:
-#if 0
- imesa->dirty |= I810_UPLOAD_CTX;
- imesa->Setup[I810_CTXREG_SC] &= ~SC_ENABLE_MASK;
- imesa->Setup[I810_CTXREG_SC] |= SC_UPDATE_SCISSOR;
- if (state)
- imesa->Setup[I810_CTXREG_SC] |= SC_ENABLE;
-#endif
+ FLUSH_BATCH(imesa);
+ imesa->scissor = state;
+ imesa->dirty |= I810_UPLOAD_CLIPRECTS;
+ break;
+ case GL_POLYGON_STIPPLE:
+ if ((ctx->Driver.TriangleCaps & DD_TRI_STIPPLE) &&
+ ctx->PB->primitive == GL_POLYGON)
+ {
+ FLUSH_BATCH(imesa);
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE;
+ }
+ break;
+ case GL_LINE_SMOOTH:
+ if (ctx->PB->primitive == GL_LINE) {
+ FLUSH_BATCH(imesa);
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
+ imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5;
+ if (state) {
+ imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+ imesa->Setup[I810_CTXREG_LCS] |= LCS_LINEWIDTH_0_5;
+ }
+ }
+ break;
+ case GL_POINT_SMOOTH:
+ if (ctx->PB->primitive == GL_POINT) {
+ FLUSH_BATCH(imesa);
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+ }
+ break;
+ case GL_POLYGON_SMOOTH:
+ if (ctx->PB->primitive == GL_POLYGON) {
+ FLUSH_BATCH(imesa);
+ imesa->dirty |= I810_UPLOAD_CTX;
+ imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
+ if (state)
+ imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
+ }
break;
case GL_FOG:
+ FLUSH_BATCH(imesa);
imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_B1] &= ~B1_FOG_ENABLE;
- imesa->Setup[I810_CTXREG_B1] |= B1_UPDATE_FOG_ENABLE;
if (state)
imesa->Setup[I810_CTXREG_B1] |= B1_FOG_ENABLE;
break;
case GL_CULL_FACE:
if (ctx->PB->primitive == GL_POLYGON) {
+ FLUSH_BATCH(imesa);
imesa->dirty |= I810_UPLOAD_CTX;
imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
- imesa->Setup[I810_CTXREG_LCS] |= LCS_UPDATE_CULL_MODE;
if (state)
imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsCullMode;
else
imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE;
}
break;
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_3D:
+ FLUSH_BATCH(imesa);
+ imesa->new_state |= I810_NEW_TEXTURE;
+ break;
case GL_TEXTURE_2D:
+ FLUSH_BATCH(imesa);
imesa->new_state |= I810_NEW_TEXTURE;
imesa->dirty |= I810_UPLOAD_CTX;
if (ctx->Texture.CurrentUnit == 0) {
imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL0_ENABLE;
- imesa->Setup[I810_CTXREG_MT] |= MT_UPDATE_TEXEL0_STATE;
if (state)
imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL0_ENABLE;
} else {
imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL1_ENABLE;
- imesa->Setup[I810_CTXREG_MT] |= MT_UPDATE_TEXEL1_STATE;
if (state)
imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL1_ENABLE;
}
@@ -444,92 +583,20 @@ static void i810DDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
/* =============================================================
*/
-/* Delightfully few possibilities:
- */
-void i810DDPrintState( const char *msg, GLuint state )
-{
- fprintf(stderr, "%s (0x%x): %s\n",
- msg,
- (unsigned int) state,
- (state & I810_NEW_TEXTURE) ? "texture, " : "");
-}
void i810DDUpdateHwState( GLcontext *ctx )
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
- if (imesa->new_state & I810_NEW_TEXTURE)
+ if (imesa->new_state & I810_NEW_TEXTURE) {
+ FLUSH_BATCH(imesa);
i810UpdateTextureState( ctx );
-
- imesa->new_state = 0;
-
- if (imesa->dirty) {
- LOCK_HARDWARE(imesa);
- i810EmitHwStateLocked( imesa );
- UNLOCK_HARDWARE(imesa);
- }
-}
-
-
-
-/*
- * i810DmaExecute
- * Add a block of data to the dma buffer
- *
- * -- In ring buffer mode, must be called with lock held, and translates to
- * OUT_RING rather than outbatch
- *
- * -- In dma mode, probably won't be used because state updates will have
- * to be done via the kernel for security...
- */
-static void i810DmaExecute( i810ContextPtr imesa,
- GLuint *code, int dwords, const char *where )
-{
- if (I810_DEBUG & DEBUG_VERBOSE_RING)
- fprintf(stderr, "i810DmaExecute (%s)\n", where);
-
- if (dwords & 1) {
- i810Error( "Misaligned buffer in i810DmaExecute\n" );
- exit(1);
}
- {
- int i;
- BEGIN_BATCH( imesa, dwords);
-
- for ( i = 0 ; i < dwords ; i++ ) {
- if (0) fprintf(stderr, "%d: %x\n", i, code[i]);
- OUT_BATCH( code[i] );
- }
-
- ADVANCE_BATCH();
- }
+ imesa->new_state = 0;
}
-
-void i810EmitScissorValues( i810ContextPtr imesa, int nr, int emit )
-{
- int x1 = imesa->pClipRects[nr].x1 - imesa->drawX;
- int y1 = imesa->pClipRects[nr].y1 - imesa->drawY;
- int x2 = imesa->pClipRects[nr].x2 - imesa->drawX;
- int y2 = imesa->pClipRects[nr].y2 - imesa->drawY;
-
- if (I810_DEBUG&DEBUG_VERBOSE_DRI)
- fprintf(stderr, "i810EmitScissorValues %d,%d - %d,%d\n",
- x1,y1,x2,y2);
-
- imesa->ClipSetup[I810_CLIPREG_SCI1] = (x1 | (y1 << 16));
- imesa->ClipSetup[I810_CLIPREG_SCI2] = (x2 | (y2 << 16));
- imesa->ClipSetup[I810_CLIPREG_SC] = ( GFX_OP_SCISSOR |
- SC_UPDATE_SCISSOR |
- SC_ENABLE );
-
- if (emit)
- i810DmaExecute( imesa,
- imesa->ClipSetup, I810_CLIP_SETUP_SIZE, "cliprect" );
-}
-
void i810EmitDrawingRectangle( i810ContextPtr imesa )
{
__DRIdrawablePrivate *dPriv = imesa->driDrawable;
@@ -545,7 +612,6 @@ void i810EmitDrawingRectangle( i810ContextPtr imesa )
*/
imesa->BufferSetup[I810_DESTREG_DR4] = ((y0<<16) |
(((unsigned)x0)&0xFFFF));
-
/* Clip to screen.
*/
@@ -556,74 +622,74 @@ void i810EmitDrawingRectangle( i810ContextPtr imesa )
/* Onscreen drawing rectangle.
- *
- * TODO: clip again to GL scissor values.
*/
imesa->BufferSetup[I810_DESTREG_DR2] = ((y0<<16) | x0);
- imesa->BufferSetup[I810_DESTREG_DR3] = ((y1<<16) | x1);
+ imesa->BufferSetup[I810_DESTREG_DR3] = (((y1+1)<<16) | (x1+1));
imesa->dirty |= I810_UPLOAD_BUFFERS;
}
static void i810DDPrintDirty( const char *msg, GLuint state )
{
- fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n",
+ fprintf(stderr, "%s (0x%x): %s%s%s%s%s\n",
msg,
(unsigned int) state,
- (state & I810_REFRESH_RING) ? "read-lp-ring, " : "",
- (state & I810_REQUIRE_QUIESCENT) ? "req-quiescent, " : "",
(state & I810_UPLOAD_TEX0IMAGE) ? "upload-tex0, " : "",
(state & I810_UPLOAD_TEX1IMAGE) ? "upload-tex1, " : "",
(state & I810_UPLOAD_CTX) ? "upload-ctx, " : "",
(state & I810_UPLOAD_BUFFERS) ? "upload-bufs, " : "",
- (state & I810_EMIT_CLIPRECT) ? "emit-single-cliprect, " : ""
+ (state & I810_UPLOAD_CLIPRECTS) ? "upload-cliprects, " : ""
);
}
-/* Spew the state onto the ringbuffer and/or texture memory.
+/* Push the state into the sarea and/or texture memory.
*/
void i810EmitHwStateLocked( i810ContextPtr imesa )
{
if (I810_DEBUG & DEBUG_VERBOSE_API)
- i810DDPrintDirty( "i810EmitHwStateLocked", imesa->dirty );
-
- if (imesa->dirty & I810_REQUIRE_QUIESCENT) {
- i810glx.c_drawWaits += _I810Sync( imesa );
- }
+ i810DDPrintDirty( "\n\n\ni810EmitHwStateLocked", imesa->dirty );
- /* TODO: Refine mechanism to be equivalent to UploadSubImage
- */
- if ((imesa->dirty & I810_UPLOAD_TEX0IMAGE) && imesa->CurrentTexObj[0])
- i810UploadTexImages(imesa, imesa->CurrentTexObj[0]);
+ if (imesa->dirty & ~I810_UPLOAD_CLIPRECTS)
+ {
+ if ((imesa->dirty & I810_UPLOAD_TEX0IMAGE) && imesa->CurrentTexObj[0])
+ i810UploadTexImages(imesa, imesa->CurrentTexObj[0]);
- if ((imesa->dirty & I810_UPLOAD_TEX1IMAGE) && imesa->CurrentTexObj[1])
- i810UploadTexImages(imesa, imesa->CurrentTexObj[1]);
+ if ((imesa->dirty & I810_UPLOAD_TEX1IMAGE) && imesa->CurrentTexObj[1])
+ i810UploadTexImages(imesa, imesa->CurrentTexObj[1]);
- if ((imesa->dirty & I810_UPLOAD_CTX)) {
- i810DmaExecute( imesa, imesa->Setup, I810_CTX_SETUP_SIZE, "context" );
-
- if (imesa->CurrentTexObj[0])
- i810DmaExecute( imesa, imesa->CurrentTexObj[0]->Setup,
- I810_TEX_SETUP_SIZE, "tex-0");
+ if (imesa->dirty & I810_UPLOAD_CTX)
+ memcpy( imesa->sarea->ContextState,
+ imesa->Setup,
+ sizeof(imesa->Setup) );
+
+ if ((imesa->dirty & I810_UPLOAD_TEX0) && imesa->CurrentTexObj[0]) {
+ imesa->sarea->dirty |= I810_UPLOAD_TEX0;
+ memcpy(imesa->sarea->TexState[0],
+ imesa->CurrentTexObj[0]->Setup,
+ sizeof(imesa->sarea->TexState[0]));
+ }
- if (imesa->CurrentTexObj[1])
- i810DmaExecute( imesa, imesa->CurrentTexObj[1]->Setup,
- I810_TEX_SETUP_SIZE, "tex-1");
+ if ((imesa->dirty & I810_UPLOAD_TEX1) && imesa->CurrentTexObj[1]) {
+ imesa->sarea->dirty |= I810_UPLOAD_TEX1;
+ memcpy(imesa->sarea->TexState[1],
+ imesa->CurrentTexObj[1]->Setup,
+ sizeof(imesa->sarea->TexState[1]));
+ }
+
+ if (imesa->dirty & I810_UPLOAD_BUFFERS)
+ memcpy( imesa->sarea->BufferState,
+ imesa->BufferSetup,
+ sizeof(imesa->BufferSetup) );
+
+ imesa->sarea->dirty |= (imesa->dirty &
+ ~(I810_UPLOAD_TEX1|I810_UPLOAD_TEX0));
+ imesa->dirty &= I810_UPLOAD_CLIPRECTS;
}
-
- if (imesa->dirty & I810_UPLOAD_BUFFERS)
- i810DmaExecute( imesa, imesa->BufferSetup,
- I810_DEST_SETUP_SIZE, "buffers" );
-
- if (imesa->dirty & I810_EMIT_CLIPRECT)
- i810DmaExecute( imesa, imesa->ClipSetup,
- I810_CLIP_SETUP_SIZE, "cliprect" );
-
- imesa->dirty = 0;
}
+
void i810DDInitState( i810ContextPtr imesa )
{
i810ScreenPrivate *i810Screen = imesa->i810Screen;
@@ -797,7 +863,7 @@ void i810DDInitState( i810ContextPtr imesa )
LCS_UPDATE_ZMODE |
LCS_Z_LESS |
LCS_UPDATE_LINEWIDTH |
- (0x2<<LCS_LINEWIDTH_SHIFT) |
+ LCS_LINEWIDTH_1_0 |
LCS_UPDATE_ALPHA_INTERP |
LCS_ALPHA_INTERP |
LCS_UPDATE_FOG_INTERP |
@@ -825,11 +891,9 @@ void i810DDInitState( i810ContextPtr imesa )
imesa->Setup[I810_CTXREG_ST0] = GFX_OP_STIPPLE;
imesa->Setup[I810_CTXREG_ST1] = 0;
-
-
imesa->Setup[I810_CTXREG_AA] = ( GFX_OP_ANTIALIAS |
AA_UPDATE_EDGEFLAG |
- 0 |
+ AA_ENABLE_EDGEFLAG | /* ? */
AA_UPDATE_POLYWIDTH |
AA_POLYWIDTH_05 |
AA_UPDATE_LINEWIDTH |
@@ -839,38 +903,29 @@ void i810DDInitState( i810ContextPtr imesa )
AA_UPDATE_AA_ENABLE |
0 );
-
-
- memset(imesa->ClipSetup, 0, sizeof(imesa->ClipSetup));
- imesa->ClipSetup[I810_CLIPREG_SCI0] = GFX_OP_SCISSOR_INFO;
- imesa->ClipSetup[I810_CLIPREG_SCI1] = 0;
- imesa->ClipSetup[I810_CLIPREG_SCI2] = 0;
- imesa->ClipSetup[I810_CLIPREG_SC] = ( GFX_OP_SCISSOR |
- SC_UPDATE_SCISSOR |
- 0 );
-
- /* This stuff is all invarient as long as we are using
- * shared back and depth buffers.
- */
memset(imesa->BufferSetup, 0, sizeof(imesa->BufferSetup));
- imesa->drawOffset = i810Screen->backOffset;
imesa->BufferSetup[I810_DESTREG_DI0] = CMD_OP_DESTBUFFER_INFO;
- if (imesa->glCtx->Color.DriverDrawBuffer == GL_BACK_LEFT)
+ if (imesa->glCtx->Color.DriverDrawBuffer == GL_BACK_LEFT) {
+ imesa->drawMap = i810Screen->back.map;
imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->backOffset |
- i810Screen->auxPitchBits);
- else
+ i810Screen->backPitchBits);
+ } else {
+ imesa->drawMap = imesa->driScreen->pFB;
imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->fbOffset |
- i810Screen->auxPitchBits);
+ i810Screen->backPitchBits);
+ }
+ if (imesa->glCtx->Color.DriverDrawBuffer == GL_BACK_LEFT) {
+ imesa->readMap = i810Screen->back.map;
+ } else {
+ imesa->readMap = imesa->driScreen->pFB;
+ }
imesa->BufferSetup[I810_DESTREG_DV0] = GFX_OP_DESTBUFFER_VARS;
imesa->BufferSetup[I810_DESTREG_DV1] = (DV_HORG_BIAS_OGL |
DV_VORG_BIAS_OGL |
i810Screen->fbFormat);
- imesa->BufferSetup[I810_DESTREG_ZB0] = CMD_OP_Z_BUFFER_INFO;
- imesa->BufferSetup[I810_DESTREG_ZB1] = (i810Screen->depthOffset |
- i810Screen->auxPitchBits);
imesa->BufferSetup[I810_DESTREG_DR0] = GFX_OP_DRAWRECT_INFO;
imesa->BufferSetup[I810_DESTREG_DR1] = DR1_RECT_CLIP_ENABLE;
@@ -886,17 +941,31 @@ void i810DDUpdateState( GLcontext *ctx )
{
i810ContextPtr imesa = I810_CONTEXT( ctx );
+ /* Have to do this here to detect texture fallbacks in time:
+ */
+ if (I810_CONTEXT(ctx)->new_state & I810_NEW_TEXTURE)
+ i810DDUpdateHwState( ctx );
+
+
if (ctx->NewState & INTERESTED) {
i810DDChooseRenderState(ctx);
i810ChooseRasterSetupFunc(ctx);
}
+
+ if (0)
+ fprintf(stderr, "IndirectTriangles %x Fallback %x\n",
+ imesa->IndirectTriangles, imesa->Fallback);
- /* TODO: stop mesa from clobbering these.
- */
- ctx->Driver.PointsFunc=imesa->PointsFunc;
- ctx->Driver.LineFunc=imesa->LineFunc;
- ctx->Driver.TriangleFunc=imesa->TriangleFunc;
- ctx->Driver.QuadFunc=imesa->QuadFunc;
+ if (!imesa->Fallback)
+ {
+ ctx->IndirectTriangles &= ~DD_SW_RASTERIZE;
+ ctx->IndirectTriangles |= imesa->IndirectTriangles;
+
+ ctx->Driver.PointsFunc=imesa->PointsFunc;
+ ctx->Driver.LineFunc=imesa->LineFunc;
+ ctx->Driver.TriangleFunc=imesa->TriangleFunc;
+ ctx->Driver.QuadFunc=imesa->QuadFunc;
+ }
}
@@ -919,8 +988,13 @@ void i810DDInitStateFuncs(GLcontext *ctx)
ctx->Driver.ReducedPrimitiveChange = i810DDReducedPrimitiveChange;
ctx->Driver.RenderStart = i810DDUpdateHwState;
ctx->Driver.RenderFinish = 0;
+
+ ctx->Driver.PolygonStipple = i810DDPolygonStipple;
+ ctx->Driver.LineStipple = 0;
+
+ ctx->Driver.SetReadBuffer = i810DDSetReadBuffer;
+ ctx->Driver.SetDrawBuffer = i810DDSetDrawBuffer;
- ctx->Driver.SetBuffer = i810DDSetBuffer;
ctx->Driver.Color = i810DDSetColor;
ctx->Driver.ClearColor = i810DDClearColor;
ctx->Driver.Dither = i810DDDither;
@@ -928,6 +1002,5 @@ void i810DDInitStateFuncs(GLcontext *ctx)
ctx->Driver.Index = 0;
ctx->Driver.ClearIndex = 0;
ctx->Driver.IndexMask = 0;
-
}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810state.h b/xc/lib/GL/mesa/src/drv/i810/i810state.h
index d0551631e..b43a1a4ff 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810state.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810state.h
@@ -1,13 +1,12 @@
#ifndef _I810_STATE_H
#define _I810_STATE_H
+#include "i810context.h"
extern void i810DDUpdateHwState( GLcontext *ctx );
extern void i810DDUpdateState( GLcontext *ctx );
extern void i810DDInitState( i810ContextPtr imesa );
extern void i810DDInitStateFuncs( GLcontext *ctx );
-extern void i810DDPrintState( const char *msg, GLuint state );
-
#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810swap.c b/xc/lib/GL/mesa/src/drv/i810/i810swap.c
deleted file mode 100644
index 9220ef9f4..000000000
--- a/xc/lib/GL/mesa/src/drv/i810/i810swap.c
+++ /dev/null
@@ -1,259 +0,0 @@
-
-
-#include "types.h"
-#include "vbrender.h"
-#include "i810log.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "mm.h"
-#include "i810lib.h"
-#include "i810dd.h"
-#include "i810dma.h"
-#include "i810state.h"
-#include "i810swap.h"
-#include "i810dma.h"
-
-/*
- * i810BackToFront
- *
- * Blit the visible rectangles from the back buffer to the screen.
- * Respects the frontbuffer cliprects, and applies the offset
- * necessary if the backbuffer is positioned elsewhere in the screen.
- */
-static int i810BackToFront( i810ContextPtr imesa )
-{
- __DRIdrawablePrivate *dPriv = imesa->driDrawable;
- i810ScreenPrivate *i810Screen = imesa->i810Screen;
-
-
- /* Use the frontbuffer cliprects:
- */
- XF86DRIClipRectPtr pbox = dPriv->pClipRects;
- int nbox = dPriv->numClipRects;
-
- if( nbox )
- {
- int i;
- int pitch = i810Screen->auxPitch;
-
- int dx = dPriv->auxX - dPriv->x;
- int dy = dPriv->auxY - dPriv->y;
- int ofs = ( i810Screen->backOffset +
- dy * i810Screen->auxPitch +
- dx * i810Screen->cpp);
-
- unsigned int BR13 = ((i810Screen->fbStride) |
- (0xCC << 16));
-
-
- for (i=0; i < nbox; i++, pbox++) {
- int w = pbox->x2 - pbox->x1;
- int h = pbox->y2 - pbox->y1;
-
- int start = ofs + pbox->x1*i810Screen->cpp + pbox->y1*pitch;
- int dst = pbox->x1*i810Screen->cpp + pbox->y1*i810Screen->fbStride;
-
- if (I810_DEBUG&DEBUG_VERBOSE_2D)
- fprintf(stderr, "i810BackToFront %d,%d-%dx%d\n",
- pbox->x1,pbox->y1,w,h);
-
- {
- BEGIN_BATCH( imesa, 6 );
- OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 );
- OUT_BATCH( BR13 ); /* dest pitch, rop */
-
- OUT_BATCH( (h << 16) | (w * i810Screen->cpp));
- OUT_BATCH( dst );
-
- OUT_BATCH( pitch ); /* src pitch */
- OUT_BATCH( start );
- ADVANCE_BATCH();
- }
- }
- }
-
- return Success;
-}
-
-
-/*
- * ClearBox
- *
- * Add hardware commands to draw a filled box for the debugging
- * display. These are drawn into the current drawbuffer, so should
- * work with both front and backbuffer rendering. (However, it
- * is only ever called on swapbuffer - ie backbuffer rendering).
- */
-static void ClearBox( i810ContextPtr imesa,
- int cx, int cy, int cw, int ch,
- int r, int g, int b )
-{
- __DRIdrawablePrivate *dPriv = imesa->driDrawable;
- i810ScreenPrivate *i810Screen = imesa->i810Screen;
-
- int _nc = imesa->numClipRects;
-
- while (_nc--) {
- int x1 = cx + dPriv->x;
- int y1 = cy + dPriv->y;
- int x2 = x1 + cw;
- int y2 = y1 + ch;
-
- if (imesa->needClip) {
- int rx1 = imesa->pClipRects[_nc].x1;
- int ry1 = imesa->pClipRects[_nc].y1;
- int rx2 = imesa->pClipRects[_nc].x2;
- int ry2 = imesa->pClipRects[_nc].y2;
-
-
- if (x2 < rx1) continue;
- if (y2 < ry1) continue;
- if (x1 > rx2) continue;
- if (y1 > ry2) continue;
- if (x1 < rx1) x1 = rx1;
- if (y1 < ry1) y1 = ry1;
- if (x2 > rx2) x2 = rx2;
- if (y2 > ry2) y2 = ry2;
- }
-
-
- {
- int start = (imesa->drawOffset +
- y1 * i810Screen->auxPitch +
- x1 * i810Screen->cpp);
-
- BEGIN_BATCH( imesa, 6 );
-
- OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 );
- OUT_BATCH( BR13_SOLID_PATTERN |
- (0xF0 << 16) |
- i810Screen->auxPitch );
- OUT_BATCH( ((y2-y1) << 16) | ((x2-x1) * i810Screen->cpp));
- OUT_BATCH( start );
- OUT_BATCH( i810PackColor( i810Screen->fbFormat, r, g, b, 0 ) );
- OUT_BATCH( 0 );
-
- if (I810_DEBUG&DEBUG_VERBOSE_2D)
- fprintf(stderr, "box %d,%x %d,%d col %x (%d,%d,%d)\n",
- (int)x1,(int)y1, (int)x2,(int)y2,
- (int)i810PackColor( i810Screen->fbFormat, r, g, b, 0 ),
- (int)r, (int)g, (int)b);
-
- ADVANCE_BATCH();
- }
- }
-}
-
-
-/*
- * performanceBoxes
- * Draw some small boxesin the corner of the buffer
- * based on some performance information
- */
-static void i810PerformanceBoxes( i810ContextPtr imesa ) {
-
-
- /* draw a box to show we are active, so if it is't seen it means
- that it is completely software based. Purple is traditional for
- direct rendering */
- ClearBox( imesa, 4, 4, 8, 8, 255, 0, 255 );
-
- /* draw a red box if we had to wait for drawing to complete
- (software render or texture swap) */
- if ( i810glx.c_drawWaits ) {
- ClearBox( imesa, 16, 4, 8, 8, 255, 0, 0 );
- i810glx.c_drawWaits = 0;
- }
-
- /* draw a blue box if the 3d context was lost
- */
- if ( i810glx.c_ctxlost ) {
- ClearBox( imesa, 28, 4, 8, 8, 0, 0, 255 );
- i810glx.c_ctxlost = 0;
- }
-
- /* draw an orange box if texture state was stomped */
- if ( i810glx.c_texlost ) {
- ClearBox( imesa, 40, 4, 8, 8, 255, 128, 0 );
- i810glx.c_texlost = 0;
- }
-
- /* draw a yellow box if textures were swapped */
- if ( i810glx.c_textureSwaps ) {
- ClearBox( imesa, 56, 4, 8, 8, 255, 255, 0 );
- i810glx.c_textureSwaps = 0;
- }
-
- /* draw a green box if we had to wait for dma to complete (full utilization)
- on the previous frame */
- if ( !i810glx.hardwareWentIdle ) {
- ClearBox( imesa, 72, 4, 8, 8, 0, 255, 0 );
- }
- i810glx.hardwareWentIdle = 0;
-
-#if 0
- /* show buffer utilization */
- if ( i810glx.c_dmaFlush > 1 ) {
- /* draw a solid bar if we flushed more than one buffer */
- ClearBox( imesa, 4, 16, 252, 4, 255, 32, 32 );
- } else {
- /* draw bars to represent the utilization of primary and
- secondary buffers */
- ClearBox( imesa, 4, 16, 252, 4, 32, 32, 32 );
- t = i810glx.dma_buffer->mem.Size;
- w = 252 * i810glx.dma_buffer->head / t;
- if ( w < 1 ) {
- w = 1;
- }
- ClearBox( imesa, 4, 16, w, 4, 196, 128, 128 );
- }
-#endif
-
- i810glx.c_dmaFlush = 0;
-}
-
-
-static void i810SendDmaFlush( i810ContextPtr imesa )
-{
- BEGIN_BATCH( imesa, 2 );
- OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH );
- OUT_BATCH( 0 );
- ADVANCE_BATCH();
-}
-
-void i810SwapBuffers( i810ContextPtr imesa )
-{
- if (I810_DEBUG & DEBUG_VERBOSE_API)
- fprintf(stderr, "i810SwapBuffers()\n");
-
- LOCK_HARDWARE( imesa );
- i810SendDmaFlush( imesa );
- if ( i810glx.boxes )
- i810PerformanceBoxes( imesa );
- i810BackToFront( imesa );
-
- /* Check if we are emitting thousands of tiny frames, and if so
- * throttle them. Would be better to simply go to sleep until
- * our stuff had cleared, rather than polling. A dma solution
- * should provide for this.
- */
- if (imesa->lastSwap >= imesa->sarea->lastWrap &&
- imesa->lastSwap >= imesa->sarea->lastSync) {
-
- if (I810_DEBUG & DEBUG_VERBOSE_API)
- fprintf(stderr, ".");
-
- _I810Sync( imesa );
- }
-
- imesa->lastSwap = imesa->sarea->lastSync;
- if (imesa->sarea->lastWrap > imesa->lastSwap)
- imesa->lastSwap = imesa->sarea->lastWrap;
-
-
- UNLOCK_HARDWARE( imesa );
-
-/* XSync(imesa->display, 0); */
-}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810swap.h b/xc/lib/GL/mesa/src/drv/i810/i810swap.h
deleted file mode 100644
index 1657a717d..000000000
--- a/xc/lib/GL/mesa/src/drv/i810/i810swap.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef I810_SWAP_H
-#define I810_SWAP_H
-
-extern void i810SwapBuffers( i810ContextPtr imesa );
-
-#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tex.c b/xc/lib/GL/mesa/src/drv/i810/i810tex.c
index 039c0af59..8c88f2b2b 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810tex.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tex.c
@@ -28,9 +28,10 @@
#include <GL/gl.h>
#include "mm.h"
-#include "i810lib.h"
+#include "i810context.h"
#include "i810tex.h"
#include "i810log.h"
+#include "i810ioctl.h"
#include "simple_list.h"
#include "enums.h"
@@ -204,6 +205,7 @@ static i810TextureObjectPtr i810CreateTexObj(i810ContextPtr imesa,
log_pitch++;
t->dirty_images = 0;
+ t->bound = 0;
for ( height = i = 0 ; i < I810_TEX_MAXLEVELS && tObj->Image[i] ; i++ ) {
t->image[i].image = tObj->Image[i];
@@ -278,24 +280,24 @@ static i810TextureObjectPtr i810CreateTexObj(i810ContextPtr imesa,
void i810DestroyTexObj(i810ContextPtr imesa, i810TextureObjectPtr t)
{
- int i;
if (!t) return;
/* This is sad - need to sync *in case* we upload a texture
* to this newly free memory...
*/
if (t->MemBlock) {
- imesa->dirty |= I810_REQUIRE_QUIESCENT;
mmFreeMem(t->MemBlock);
- t->MemBlock = 0;
+ t->MemBlock = 0;
+
+ if (t->age > imesa->dirtyAge)
+ imesa->dirtyAge = t->age;
}
if (t->globj)
t->globj->DriverData = 0;
- for ( i = 0 ; i < 2 ; i++ )
- if ( imesa->CurrentTexObj[i] == t )
- imesa->CurrentTexObj[i] = 0;
+ if (t->bound)
+ imesa->CurrentTexObj[t->bound - 1] = 0;
remove_from_list(t);
free(t);
@@ -305,9 +307,11 @@ void i810DestroyTexObj(i810ContextPtr imesa, i810TextureObjectPtr t)
static void i810SwapOutTexObj(i810ContextPtr imesa, i810TextureObjectPtr t)
{
if (t->MemBlock) {
- imesa->dirty |= I810_REQUIRE_QUIESCENT;
mmFreeMem(t->MemBlock);
t->MemBlock = 0;
+
+ if (t->age > imesa->dirtyAge)
+ imesa->dirtyAge = t->age;
}
t->dirty_images = ~0;
@@ -413,13 +417,28 @@ static void i810UploadTexLevel( i810TextureObjectPtr t, int level )
}
break;
+ case GL_ALPHA:
+ {
+ GLushort *dst = (GLushort *)(t->BufAddr + t->image[level].offset);
+ GLubyte *src = (GLubyte *)image->Data;
+ i810Msg(10," CopyA: %p %p\n", dst, src);
+
+ for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) {
+ for (i = 0 ; i < image->Width ; i++) {
+ dst[i] = I810PACKCOLOR4444(255,255,255,src[0]);
+ src += 1;
+ }
+ }
+ }
+ break;
+
/* TODO: Translate color indices *now*:
*/
case GL_COLOR_INDEX:
{
GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[level].offset);
GLubyte *src = (GLubyte *)image->Data;
- i810Msg(10," CopyIndex %p %p\n", dst, src);
+ i810Msg(10," CopyIndex: %p %p\n", dst, src);
for (j = 0 ; j < image->Height ; j++, dst += t->Pitch) {
for (i = 0 ; i < image->Width ; i++) {
@@ -431,8 +450,8 @@ static void i810UploadTexLevel( i810TextureObjectPtr t, int level )
break;
default:
- i810Error("Not supported texture format %d\n",(int)image->Format);
- exit(1);
+ i810Error("Not supported texture format %s\n",
+ gl_lookup_enum_by_nr(image->Format));
}
}
@@ -449,13 +468,19 @@ void i810PrintLocalLRU( i810ContextPtr imesa )
t->MemBlock->ofs / sz,
t->MemBlock->ofs,
t->MemBlock->size);
+ else
+ fprintf(stderr, "Texture (bound %d) at %x sz %x\n",
+ t->bound,
+ t->MemBlock->ofs,
+ t->MemBlock->size);
+
}
}
void i810PrintGlobalLRU( i810ContextPtr imesa )
{
int i, j;
- i810TexRegion *list = imesa->sarea->texList;
+ drm_i810_tex_region_t *list = imesa->sarea->texList;
for (i = 0, j = I810_NR_TEX_REGIONS ; i < I810_NR_TEX_REGIONS ; i++) {
fprintf(stderr, "list[%d] age %d next %d prev %d\n",
@@ -471,7 +496,7 @@ void i810PrintGlobalLRU( i810ContextPtr imesa )
void i810ResetGlobalLRU( i810ContextPtr imesa )
{
- i810TexRegion *list = imesa->sarea->texList;
+ drm_i810_tex_region_t *list = imesa->sarea->texList;
int sz = 1 << imesa->i810Screen->logTextureGranularity;
int i;
@@ -481,7 +506,7 @@ void i810ResetGlobalLRU( i810ContextPtr imesa )
* when looking up objects at a particular location in texture
* memory.
*/
- for (i = 0 ; (i+1) * sz < imesa->i810Screen->textureSize ; i++) {
+ for (i = 0 ; (i+1) * sz <= imesa->i810Screen->textureSize ; i++) {
list[i].prev = i-1;
list[i].next = i+1;
list[i].age = 0;
@@ -503,7 +528,7 @@ static void i810UpdateTexLRU( i810ContextPtr imesa, i810TextureObjectPtr t )
int logsz = imesa->i810Screen->logTextureGranularity;
int start = t->MemBlock->ofs >> logsz;
int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz;
- i810TexRegion *list = imesa->sarea->texList;
+ drm_i810_tex_region_t *list = imesa->sarea->texList;
imesa->texAge = ++imesa->sarea->texAge;
@@ -556,7 +581,7 @@ void i810TexturesGone( i810ContextPtr imesa,
/* It overlaps - kick it off. Need to hold onto the currently bound
* objects, however.
*/
- if (t == imesa->CurrentTexObj[0] || t == imesa->CurrentTexObj[1])
+ if (t->bound)
i810SwapOutTexObj( imesa, t );
else
i810DestroyTexObj( imesa, t );
@@ -583,7 +608,6 @@ int i810UploadTexImages( i810ContextPtr imesa, i810TextureObjectPtr t )
{
int i;
int ofs;
- i810glx.c_textureSwaps++;
/* Do we need to eject LRU texture objects?
*/
@@ -594,18 +618,24 @@ int i810UploadTexImages( i810ContextPtr imesa, i810TextureObjectPtr t )
if (t->MemBlock)
break;
+ if (imesa->TexObjList.prev->bound) {
+ fprintf(stderr, "Hit bound texture in upload\n");
+ i810PrintLocalLRU( imesa );
+ return -1;
+ }
+
if (imesa->TexObjList.prev == &(imesa->TexObjList)) {
- fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize);
+ fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize);
mmDumpMemInfo( imesa->texHeap );
return -1;
}
-
+
i810DestroyTexObj( imesa, imesa->TexObjList.prev );
}
ofs = t->MemBlock->ofs;
t->Setup[I810_TEXREG_MI3] = imesa->i810Screen->textureOffset + ofs;
- t->BufAddr = i810glx.texVirtual + ofs;
+ t->BufAddr = imesa->i810Screen->tex.map + ofs;
imesa->dirty |= I810_UPLOAD_CTX;
}
@@ -613,6 +643,14 @@ int i810UploadTexImages( i810ContextPtr imesa, i810TextureObjectPtr t )
*/
i810UpdateTexLRU( imesa, t );
+ if (I810_DEBUG & DEBUG_VERBOSE_LRU)
+ fprintf(stderr, "dispatch age: %d age freed memory: %d\n",
+ GET_DISPATCH_AGE(imesa), imesa->dirtyAge);
+
+ if (imesa->dirtyAge >= GET_DISPATCH_AGE(imesa))
+ i810WaitAgeLocked( imesa, imesa->dirtyAge );
+
+
if (t->dirty_images) {
if (I810_DEBUG & DEBUG_VERBOSE_LRU)
fprintf(stderr, "*");
@@ -694,21 +732,37 @@ static void i810UpdateTex0State( GLcontext *ctx )
if (t->dirty_images)
imesa->dirty |= I810_UPLOAD_TEX0IMAGE;
-
+
imesa->CurrentTexObj[0] = t;
+ t->bound = 1;
+
+ if (t->MemBlock)
+ i810UpdateTexLRU( imesa, t );
switch (ctx->Texture.Unit[0].EnvMode) {
- case GL_REPLACE:
- imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
- MC_STAGE_0 |
- MC_UPDATE_DEST |
- MC_DEST_CURRENT |
- MC_UPDATE_ARG1 |
- MC_ARG1_TEX0_COLOR |
- MC_UPDATE_ARG2 |
- MC_ARG2_ONE |
- MC_UPDATE_OP |
- MC_OP_ARG1 );
+ case GL_REPLACE:
+ if (t->image[0].internalFormat == GL_ALPHA)
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_TEX0_COLOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ITERATED_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_ARG2 );
+ else
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_TEX0_COLOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ONE |
+ MC_UPDATE_OP |
+ MC_OP_ARG1 );
if (t->image[0].internalFormat == GL_RGB) {
ma_modulate_op = MA_OP_ARG1;
@@ -812,16 +866,28 @@ static void i810UpdateTex0State( GLcontext *ctx )
MA_OP_ARG1 );
break;
case GL_BLEND:
- imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
- MC_STAGE_0 |
- MC_UPDATE_DEST |
- MC_DEST_CURRENT |
- MC_UPDATE_ARG1 |
- MC_ARG1_COLOR_FACTOR |
- MC_UPDATE_ARG2 |
- MC_ARG2_ITERATED_COLOR |
- MC_UPDATE_OP |
- MC_OP_LIN_BLEND_TEX0_COLOR );
+ if (t->image[0].internalFormat == GL_ALPHA)
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_TEX0_COLOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ITERATED_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_ARG2 );
+ else
+ imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
+ MC_STAGE_0 |
+ MC_UPDATE_DEST |
+ MC_DEST_CURRENT |
+ MC_UPDATE_ARG1 |
+ MC_ARG1_COLOR_FACTOR |
+ MC_UPDATE_ARG2 |
+ MC_ARG2_ITERATED_COLOR |
+ MC_UPDATE_OP |
+ MC_OP_LIN_BLEND_TEX0_COLOR );
if (t->image[0].internalFormat == GL_RGB) {
imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
@@ -911,7 +977,10 @@ static void i810UpdateTex1State( GLcontext *ctx )
imesa->dirty |= I810_UPLOAD_TEX1IMAGE;
imesa->CurrentTexObj[1] = t;
+ t->bound = 2;
+ if (t->MemBlock)
+ i810UpdateTexLRU( imesa, t );
switch (ctx->Texture.Unit[1].EnvMode) {
case GL_REPLACE:
@@ -1078,11 +1147,15 @@ static void i810UpdateTex1State( GLcontext *ctx )
void i810UpdateTextureState( GLcontext *ctx )
{
i810ContextPtr imesa = I810_CONTEXT(ctx);
+ if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->bound = 0;
+ if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->bound = 0;
imesa->CurrentTexObj[0] = 0;
- imesa->CurrentTexObj[1] = 0;
+ imesa->CurrentTexObj[1] = 0;
i810UpdateTex0State( ctx );
i810UpdateTex1State( ctx );
- I810_CONTEXT( ctx )->dirty |= I810_UPLOAD_CTX;
+ I810_CONTEXT( ctx )->dirty |= (I810_UPLOAD_CTX |
+ I810_UPLOAD_TEX0 |
+ I810_UPLOAD_TEX1);
}
@@ -1091,25 +1164,30 @@ void i810UpdateTextureState( GLcontext *ctx )
* DRIVER functions
*****************************************/
-static void i810TexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param )
+static void i810TexEnv( GLcontext *ctx, GLenum target,
+ GLenum pname, const GLfloat *param )
{
i810ContextPtr imesa = I810_CONTEXT( ctx );
if (pname == GL_TEXTURE_ENV_MODE) {
+ FLUSH_BATCH(imesa);
imesa->new_state |= I810_NEW_TEXTURE;
} else if (pname == GL_TEXTURE_ENV_COLOR) {
struct gl_texture_unit *texUnit =
&ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- GLubyte c[4];
+ GLfloat *fc = texUnit->EnvColor;
GLuint col;
- FLOAT_RGBA_TO_UBYTE_RGBA(texUnit->EnvColor, c);
- col = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]);
+ col = ((((GLubyte)fc[3])<<24) |
+ (((GLubyte)fc[0])<<16) |
+ (((GLubyte)fc[1])<<8) |
+ (((GLubyte)fc[2])<<0));
if (imesa->Setup[I810_CTXREG_CF1] != col) {
+ FLUSH_BATCH(imesa);
imesa->Setup[I810_CTXREG_CF1] = col;
imesa->dirty |= I810_UPLOAD_CTX;
}
@@ -1137,6 +1215,7 @@ static void i810TexImage( GLcontext *ctx,
t = (i810TextureObjectPtr) tObj->DriverData;
if (t) {
+ if (t->bound) FLUSH_BATCH(imesa);
/* if this is the current object, it will force an update */
i810DestroyTexObj( imesa, t );
tObj->DriverData = 0;
@@ -1163,10 +1242,10 @@ static void i810TexSubImage( GLcontext *ctx, GLenum target,
t = (i810TextureObjectPtr) tObj->DriverData;
if (t) {
+ if (t->bound) FLUSH_BATCH( imesa );
i810DestroyTexObj( imesa, t );
tObj->DriverData = 0;
imesa->new_state |= I810_NEW_TEXTURE;
- i810glx.c_textureSwaps++;
}
}
@@ -1183,15 +1262,18 @@ static void i810TexParameter( GLcontext *ctx, GLenum target,
switch (pname) {
case GL_TEXTURE_MIN_FILTER:
case GL_TEXTURE_MAG_FILTER:
+ if (t->bound) FLUSH_BATCH( imesa );
i810SetTexFilter(t,tObj->MinFilter,tObj->MagFilter);
break;
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
+ if (t->bound) FLUSH_BATCH( imesa );
i810SetTexWrapping(t,tObj->WrapS,tObj->WrapT);
break;
case GL_TEXTURE_BORDER_COLOR:
+ if (t->bound) FLUSH_BATCH( imesa );
i810SetTexBorderColor(t,tObj->BorderColor);
break;
@@ -1206,7 +1288,14 @@ static void i810BindTexture( GLcontext *ctx, GLenum target,
struct gl_texture_object *tObj )
{
i810ContextPtr imesa = I810_CONTEXT( ctx );
- imesa->CurrentTexObj[ctx->Texture.CurrentUnit] = 0;
+
+ FLUSH_BATCH(imesa);
+
+ if (imesa->CurrentTexObj[ctx->Texture.CurrentUnit]) {
+ imesa->CurrentTexObj[ctx->Texture.CurrentUnit]->bound = 0;
+ imesa->CurrentTexObj[ctx->Texture.CurrentUnit] = 0;
+ }
+
imesa->new_state |= I810_NEW_TEXTURE;
}
@@ -1216,6 +1305,13 @@ static void i810DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
i810ContextPtr imesa = I810_CONTEXT( ctx );
if (t) {
+
+ if (t->bound) {
+ FLUSH_BATCH(imesa);
+ imesa->CurrentTexObj[t->bound-1] = 0;
+ imesa->new_state |= I810_NEW_TEXTURE;
+ }
+
i810DestroyTexObj(imesa,t);
tObj->DriverData=0;
}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tex.h b/xc/lib/GL/mesa/src/drv/i810/i810tex.h
index d2b153ad8..a16733ec1 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810tex.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tex.h
@@ -61,10 +61,11 @@ struct i810_texture_object_t {
int Height;
int texelBytes;
int totalSize;
+ int bound;
PMemBlock MemBlock;
char *BufAddr;
-
+
GLuint min_level;
GLuint max_level;
GLuint dirty_images;
@@ -87,8 +88,6 @@ struct i810_texture_object_t {
#define I810_UPDATE_PALETTE 0x2
#define I810_FALLBACK_PALETTE 0x4
-typedef struct i810_texture_object_t *i810TextureObjectPtr;
-
void i810UpdateTextureState( GLcontext *ctx );
void i810DDInitTextureFuncs( GLcontext *ctx );
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.c b/xc/lib/GL/mesa/src/drv/i810/i810tris.c
index 7e24da002..c601ca492 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810tris.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.c
@@ -31,7 +31,6 @@
#include "pipeline.h"
#include "mm.h"
-#include "i810lib.h"
#include "i810tris.h"
#include "i810vb.h"
#include "i810log.h"
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.h b/xc/lib/GL/mesa/src/drv/i810/i810tris.h
index 81cdb5159..3b3843683 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810tris.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.h
@@ -27,37 +27,48 @@
#define I810TRIS_INC
#include "types.h"
-#include "i810dma.h"
+#include "i810ioctl.h"
extern void i810PrintRenderState( const char *msg, GLuint state );
extern void i810DDChooseRenderState(GLcontext *ctx);
extern void i810DDTrifuncInit( void );
-extern GLuint *i810AllocPrimitiveVerts( i810ContextPtr imesa, int dwords );
-
-
-/* Todo:
- * - multidraw, ...
- * - Antialiasing (?)
- * - line and polygon stipple
- * - select and feedback
- * - stencil
- * - point parameters
- * -
- */
-#define I810_ANTIALIAS_BIT 0 /* ignored for now, no fallback */
+/* shared */
#define I810_FLAT_BIT 0x1
+
+/* triangle */
#define I810_OFFSET_BIT 0x2
#define I810_TWOSIDE_BIT 0x4
-#define I810_NODRAW_BIT 0x8
-#define I810_FALLBACK_BIT 0x10
-/* Not in use:
- */
-#define I810_FEEDBACK_BIT 0x20
-#define I810_SELECT_BIT 0x40
-#define I810_POINT_PARAM_BIT 0x80 /* not needed? */
+/* line */
+#define I810_WIDE_LINE_BIT 0x2
+#define I810_STIPPLE_LINE_BIT 0x4
+
+/* shared */
+#define I810_FALLBACK_BIT 0x8
+
+
+
+
+
+static i810_vertex __inline__ *i810AllocTriangles( i810ContextPtr imesa, int nr)
+{
+ GLuint *start = i810AllocDwords( imesa, 30*nr, PR_TRIANGLES );
+ return (i810_vertex *)start;
+}
+
+static i810_vertex __inline__ *i810AllocLine( i810ContextPtr imesa )
+{
+ GLuint *start = i810AllocDwords( imesa, 20, PR_LINES );
+ return (i810_vertex *)start;
+}
+
+static i810_vertex __inline__ *i810AllocRect( i810ContextPtr imesa )
+{
+ GLuint *start = i810AllocDwords( imesa, 30, PR_RECTS );
+ return (i810_vertex *)start;
+}
@@ -66,23 +77,17 @@ static void __inline__ i810_draw_triangle( i810ContextPtr imesa,
i810_vertex *v1,
i810_vertex *v2 )
{
- i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( imesa, 30 );
+ i810_vertex *wv = i810AllocTriangles( imesa, 1 );
wv[0] = *v0;
wv[1] = *v1;
wv[2] = *v2;
- FINISH_PRIM();
}
-
-
-/* These can go soon, but for the meantime we're using triangles for
- * everything.
- */
static __inline__ void i810_draw_point( i810ContextPtr imesa,
i810_vertex *tmp, float sz )
{
- i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( imesa, 6*10 );
+ i810_vertex *wv = i810AllocTriangles( imesa, 2 );
wv[0] = *tmp;
wv[0].x = tmp->x - sz;
@@ -108,16 +113,25 @@ static __inline__ void i810_draw_point( i810ContextPtr imesa,
wv[5].x = tmp->x - sz;
wv[5].y = tmp->y - sz;
- FINISH_PRIM();
}
-static __inline__ void i810_draw_line( i810ContextPtr imesa,
- i810_vertex *tmp0,
- i810_vertex *tmp1,
- float width )
+static __inline__ void i810_draw_line_line( i810ContextPtr imesa,
+ i810_vertex *tmp0,
+ i810_vertex *tmp1 )
{
- i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( imesa, 6 * 10 );
+ i810_vertex *wv = i810AllocLine( imesa );
+ wv[0] = *tmp0;
+ wv[1] = *tmp1;
+}
+
+static __inline__ void i810_draw_tri_line( i810ContextPtr imesa,
+ i810_vertex *tmp0,
+ i810_vertex *tmp1,
+ float width )
+{
+ i810_vertex *wv = i810AllocTriangles( imesa, 2 );
+
float dx, dy, ix, iy;
dx = tmp0->x - tmp1->x;
@@ -151,8 +165,15 @@ static __inline__ void i810_draw_line( i810ContextPtr imesa,
wv[5] = *tmp1;
wv[5].x = tmp1->x + ix;
wv[5].y = tmp1->y + iy;
+}
- FINISH_PRIM();
+
+static __inline__ void i810_draw_line( i810ContextPtr imesa,
+ i810_vertex *tmp0,
+ i810_vertex *tmp1,
+ float width )
+{
+ i810_draw_line_line( imesa, tmp0, tmp1 );
}
#endif
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h b/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h
index 97c101c17..9d6b43d93 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h
+++ b/xc/lib/GL/mesa/src/drv/i810/i810tritmp.h
@@ -63,44 +63,37 @@ static __inline__ void TAG(triangle)( GLcontext *ctx, GLuint e0,
}
#endif
- i810glx.c_triangles++;
-
- BEGIN_CLIP_LOOP(imesa)
- {
- i810_vertex *wv = (i810_vertex *)i810AllocPrimitiveVerts( imesa, 30 );
- wv[0] = *v0;
+ {
+ i810_vertex *wv = i810AllocTriangles( imesa, 1 );
+ wv[0] = *v0;
#if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT))
- *((int *)(&wv[0].color)) = c0;
+ *((int *)(&wv[0].color)) = c0;
#endif
#if (IND & I810_OFFSET_BIT)
- wv[0].z = v0->z + offset;
+ wv[0].z = v0->z + offset;
#endif
- wv[1] = *v1;
+ wv[1] = *v1;
#if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT))
- *((int *)(&wv[1].color)) = c1;
+ *((int *)(&wv[1].color)) = c1;
#endif
#if (IND & I810_OFFSET_BIT)
- wv[1].z = v1->z + offset;
+ wv[1].z = v1->z + offset;
#endif
- wv[2] = *v2;
+ wv[2] = *v2;
#if (IND & (I810_FLAT_BIT|I810_TWOSIDE_BIT))
- *((int *)(&wv[2].color)) = c2;
+ *((int *)(&wv[2].color)) = c2;
#endif
#if (IND & I810_OFFSET_BIT)
- wv[2].z = v2->z + offset;
+ wv[2].z = v2->z + offset;
#endif
-
- FINISH_PRIM();
- }
- END_CLIP_LOOP(imesa);
+ }
}
-
static void TAG(quad)( GLcontext *ctx, GLuint v0,
GLuint v1, GLuint v2, GLuint v3,
GLuint pv )
@@ -109,25 +102,35 @@ static void TAG(quad)( GLcontext *ctx, GLuint v0,
TAG(triangle)( ctx, v1, v2, v3, pv );
}
-
-#if ((IND & ~I810_FLAT_BIT) == 0)
-
static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
{
i810ContextPtr imesa = I810_CONTEXT( ctx );
i810VertexPtr i810VB = I810_DRIVER_DATA(ctx->VB)->verts;
- i810_vertex tmp0 = i810VB[v0].v;
- i810_vertex tmp1 = i810VB[v1].v;
- float width = ctx->Line.Width;
+ int tmp0, tmp1;
+ (void) tmp0; (void) tmp1;
+
if (IND & I810_FLAT_BIT) {
- *(int *)&tmp1.color = *(int *)&tmp0.color =
- *(int *)&i810VB[pv].v.color;
- }
+ tmp0 = *(int *)&i810VB[v0].v.color;
+ tmp1 = *(int *)&i810VB[v1].v.color;
+ i810VB[v0].v.color = i810VB[pv].v.color;
+ i810VB[v1].v.color = i810VB[pv].v.color;
+ }
- BEGIN_CLIP_LOOP(imesa)
- i810_draw_line( imesa, &tmp0, &tmp1, width );
- END_CLIP_LOOP(imesa);
+ if (IND & I810_WIDE_LINE_BIT)
+ {
+ i810_draw_tri_line( imesa, &i810VB[v0].v, &i810VB[v1].v,
+ ctx->Line.Width );
+ }
+ else
+ {
+ i810_draw_line_line( imesa, &i810VB[v0].v, &i810VB[v1].v );
+ }
+
+ if (IND & I810_FLAT_BIT) {
+ *(int *)&i810VB[v0].v.color = tmp0;
+ *(int *)&i810VB[v1].v.color = tmp1;
+ }
}
@@ -143,28 +146,22 @@ static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last )
* ctx->Driver.ReducedPrimitiveChange() callback.
*/
- BEGIN_CLIP_LOOP(imesa)
- for(i=first;i<=last;i++) {
- if(VB->ClipMask[i]==0) {
- i810_vertex *tmp = &i810VB[i].v;
- i810_draw_point( imesa, tmp, sz );
- }
+ for(i=first;i<=last;i++) {
+ if(VB->ClipMask[i]==0) {
+ i810_vertex *tmp = &i810VB[i].v;
+ i810_draw_point( imesa, tmp, sz );
}
- END_CLIP_LOOP(imesa);
+ }
}
-#endif
static void TAG(init)( void )
{
tri_tab[IND] = TAG(triangle);
quad_tab[IND] = TAG(quad);
-
-#if ((IND & ~I810_FLAT_BIT) == 0)
line_tab[IND] = TAG(line);
points_tab[IND] = TAG(points);
-#endif
}
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810vb.c b/xc/lib/GL/mesa/src/drv/i810/i810vb.c
index 6ba7eb9a5..6f8d163c4 100644
--- a/xc/lib/GL/mesa/src/drv/i810/i810vb.c
+++ b/xc/lib/GL/mesa/src/drv/i810/i810vb.c
@@ -23,11 +23,9 @@
*
*/
-#include "i810lib.h"
#include "i810context.h"
#include "i810vb.h"
#include "i810log.h"
-#include "i810dma.h"
#include "stages.h"
diff --git a/xc/lib/GL/mesa/src/drv/mga/Imakefile b/xc/lib/GL/mesa/src/drv/mga/Imakefile
index e4e39b747..cbcd09821 100644
--- a/xc/lib/GL/mesa/src/drv/mga/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/mga/Imakefile
@@ -1,4 +1,6 @@
+#include <Threads.tmpl>
+
#define DoNormalLib NormalLibGlx
#define DoSharedLib SharedLibGlx
#define DoExtraLib SharedLibGlx
@@ -9,38 +11,285 @@
ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
#endif
+#if defined(LinuxArchitecture)
+OS_SUBDIR = linux
+#endif
+#if defined(FreeBSDArchitecture)
+OS_SUBDIR = bsd
+#endif
+
+#ifdef i386Architecture
+#ifdef MesaUse3DNow
+ ASM_DEFS = -DUSE_MMX_ASM -DUSE_X86_ASM -DUSE_3DNOW_ASM
+#else
+ ASM_DEFS = -DUSE_MMX_ASM -DUSE_X86_ASM
+#endif
+#endif
+
+
#if BuildXF86DRI
DRI_DEFINES = GlxDefines -DDRIVERTS
DRI_INCLUDES = -I../../../../dri -I../../../../glx \
+ -I../../../dri \
-I$(TOP)/include -I$(TOP)/include/GL \
-I$(XF86OSSRC) -I$(SERVERSRC)/GL/dri \
-I$(XF86DRIVERSRC)/mga \
-I../../../include -I../.. -I../../X -I../common \
- -I$(XF86OSSRC)/linux/drm/kernel
+ -I$(XF86OSSRC)/$(OS_SUBDIR)/drm/kernel
#endif
MESA_INCLUDES = -I. -I.. -I../../include
- DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES)
- INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) \
- -I/usr/include/glide
- DRISRCS = mgaclear.c mgacnvtex.c mgadd.c mgadepth.c \
- mgafastpath.c \
+ DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) $(ASM_DEFS)
+ INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES)
+
+#if 0
+ LOSRC = ../../../../lowpc.c
+ LOOBJ = ../../../../lowpc.o
+
+ HISRC = ../../../../highpc.c
+ HIOBJ = ../../../../highpc.o
+#endif
+
+ DRISRCS = ../../../dri/dri_mesa.c \
+ ../../../../dri/dri_tmm.c
+
+ DRIOBJS = ../../../dri/dri_mesa.o \
+ ../../../../dri/dri_tmm.o
+
+ DRMSRCS = ../../../../dri/drm/xf86drm.c \
+ ../../../../dri/drm/xf86drmHash.c \
+ ../../../../dri/drm/xf86drmRandom.c \
+ ../../../../dri/drm/xf86drmSL.c
+
+ DRMOBJS = ../../../../dri/drm/xf86drm.o \
+ ../../../../dri/drm/xf86drmHash.o \
+ ../../../../dri/drm/xf86drmRandom.o \
+ ../../../../dri/drm/xf86drmSL.o
+
+
+ MGASRCS = mgaclear.c mgacnvtex.c mgadd.c \
+ mgafastpath.c mgaeltpath.c \
mgapipeline.c \
mgaspan.c mgastate.c mgatex.c \
- mgatris.c mgavb.c mgaioctl.c mga_xmesa.c
+ mgatris.c mgavb.c mgaioctl.c mga_xmesa.c mgabuffers.c
- DRIOBJS = mgaclear.o mgacnvtex.o mgadd.o mgadepth.o \
- mgafastpath.o \
+ MGAOBJS = mgaclear.o mgacnvtex.o mgadd.o \
+ mgafastpath.o mgaeltpath.o \
mgapipeline.o \
mgaspan.o mgastate.o mgatex.o \
- mgatris.o mgavb.o mgaioctl.o mga_xmesa.o
+ mgatris.o mgavb.o mgaioctl.o mga_xmesa.o mgabuffers.o
+
+ MESASRCS = ../../aatriangle.c \
+ ../../accum.c \
+ ../../alpha.c \
+ ../../alphabuf.c \
+ ../../attrib.c \
+ ../../bbox.c \
+ ../../bitmap.c \
+ ../../blend.c \
+ ../../buffers.c \
+ ../../clip.c \
+ ../../colortab.c \
+ ../../config.c \
+ ../../context.c \
+ ../../copypix.c \
+ ../../cva.c \
+ ../../debug_xform.c \
+ ../../depth.c \
+ ../../dlist.c \
+ ../../drawpix.c \
+ ../../enable.c \
+ ../../enums.c \
+ ../../eval.c \
+ ../../extensions.c \
+ ../../feedback.c \
+ ../../fog.c \
+ ../../get.c \
+ ../../glapi.c \
+ ../../glapinoop.c \
+ ../../glthread.c \
+ ../../hash.c \
+ ../../image.c \
+ ../../imaging.c \
+ ../../light.c \
+ ../../lines.c \
+ ../../logic.c \
+ ../../masking.c \
+ ../../matrix.c \
+ ../../mem.c \
+ ../../mmath.c \
+ ../../pb.c \
+ ../../pipeline.c \
+ ../../pixel.c \
+ ../../pixeltex.c \
+ ../../points.c \
+ ../../polygon.c \
+ ../../quads.c \
+ ../../rastpos.c \
+ ../../readpix.c \
+ ../../rect.c \
+ ../../scissor.c \
+ ../../shade.c \
+ ../../span.c \
+ ../../stages.c \
+ ../../state.c \
+ ../../stencil.c \
+ ../../teximage.c \
+ ../../texobj.c \
+ ../../texstate.c \
+ ../../texture.c \
+ ../../texutil.c \
+ ../../translate.c \
+ ../../triangle.c \
+ ../../varray.c \
+ ../../vb.c \
+ ../../vbcull.c \
+ ../../vbfill.c \
+ ../../vbindirect.c \
+ ../../vbrender.c \
+ ../../vbxform.c \
+ ../../vector.c \
+ ../../vertices.c \
+ ../../winpos.c \
+ ../../xform.c \
+ ../../zoom.c \
+ ../../X86/common_x86.c
+
+ MESAOBJS = ../../aatriangle.o \
+ ../../accum.o \
+ ../../alpha.o \
+ ../../alphabuf.o \
+ ../../attrib.o \
+ ../../bbox.o \
+ ../../bitmap.o \
+ ../../blend.o \
+ ../../buffers.o \
+ ../../clip.o \
+ ../../colortab.o \
+ ../../config.o \
+ ../../context.o \
+ ../../copypix.o \
+ ../../cva.o \
+ ../../debug_xform.o \
+ ../../depth.o \
+ ../../dlist.o \
+ ../../drawpix.o \
+ ../../enable.o \
+ ../../enums.o \
+ ../../eval.o \
+ ../../extensions.o \
+ ../../feedback.o \
+ ../../fog.o \
+ ../../get.o \
+ ../../hash.o \
+ ../../hint.o \
+ ../../image.o \
+ ../../imaging.o \
+ ../../light.o \
+ ../../lines.o \
+ ../../logic.o \
+ ../../masking.o \
+ ../../matrix.o \
+ ../../mem.o \
+ ../../mmath.o \
+ ../../pb.o \
+ ../../pipeline.o \
+ ../../pixel.o \
+ ../../pixeltex.o \
+ ../../points.o \
+ ../../polygon.o \
+ ../../quads.o \
+ ../../rastpos.o \
+ ../../readpix.o \
+ ../../rect.o \
+ ../../scissor.o \
+ ../../shade.o \
+ ../../span.o \
+ ../../stages.o \
+ ../../state.o \
+ ../../stencil.o \
+ ../../teximage.o \
+ ../../texobj.o \
+ ../../texstate.o \
+ ../../texture.o \
+ ../../texutil.o \
+ ../../translate.o \
+ ../../triangle.o \
+ ../../varray.o \
+ ../../vb.o \
+ ../../vbcull.o \
+ ../../vbfill.o \
+ ../../vbindirect.o \
+ ../../vbrender.o \
+ ../../vbxform.o \
+ ../../vector.o \
+ ../../vertices.o \
+ ../../winpos.o \
+ ../../xform.o \
+ ../../zoom.o
+
+#ifdef i386Architecture
+ X86_SRCS = ../../X86/x86.c \
+ ../../X86/x86a.S \
+ ../../X86/common_x86.c \
+ ../../X86/common_x86asm.S \
+ ../../X86/vertex.S
+
+ X86_OBJS = ../../X86/x86.o \
+ ../../X86/x86a.o \
+ ../../X86/common_x86.o \
+ ../../X86/common_x86asm.o \
+ ../../X86/vertex.o
+
+ MMX_SRCS = ../../X86/mmx_blend.S
+
+ MMX_OBJS = ../../X86/mmx_blend.o
+
+#ifdef MesaUse3DNow
+ 3DNOW_SRCS = ../../X86/3dnow.c \
+ ../../X86/3dnow_norm_raw.S \
+ ../../X86/3dnow_xform_masked1.S \
+ ../../X86/3dnow_xform_masked2.S \
+ ../../X86/3dnow_xform_masked3.S \
+ ../../X86/3dnow_xform_masked4.S \
+ ../../X86/3dnow_xform_raw1.S \
+ ../../X86/3dnow_xform_raw2.S \
+ ../../X86/3dnow_xform_raw3.S \
+ ../../X86/3dnow_xform_raw4.S \
+ ../../X86/vertex_3dnow.S
+ 3DNOW_OBJS = ../../X86/3dnow.o \
+ ../../X86/3dnow_norm_raw.o \
+ ../../X86/3dnow_xform_masked1.o \
+ ../../X86/3dnow_xform_masked2.o \
+ ../../X86/3dnow_xform_masked3.o \
+ ../../X86/3dnow_xform_masked4.o \
+ ../../X86/3dnow_xform_raw1.o \
+ ../../X86/3dnow_xform_raw2.o \
+ ../../X86/3dnow_xform_raw3.o \
+ ../../X86/3dnow_xform_raw4.o \
+ ../../X86/vertex_3dnow.o
+
+#endif
+#endif
+
+ ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS)
+ ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS)
+
+ COMMONSRCS = ../common/mm.c ../common/hwlog.c
+ COMMONOBJS = ../common/mm.o ../common/hwlog.o
+
+ SRCS = $(LOWSRC) $(DRISRCS) $(DRMSRCS) $(MESASRCS) $(ASMSRCS) $(COMMONSRCS) $(MGASRCS) $(HISRC)
+ OBJS = $(LOWOBJ) $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) $(ASMOBJS) $(COMMONOBJS) $(MGAOBJS) $(HIOBJ)
+
+REQUIREDLIBS += -lm
+#if !GlxBuiltInMga
+REQUIREDLIBS += -L../../../.. -lGL
+#endif
- SRCS = $(DRISRCS)
- OBJS = $(DRIOBJS)
#if !GlxUseBuiltInDRIDriver
#undef DoNormalLib NormalLibGlx
@@ -61,7 +310,7 @@ LIBNAME = mga_dri.so
ALL_OBJS = $(OBJS)
ALL_DEPS = DONE
SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS))
-InstallDynamicModule($(LIBNAME),$(MODULEDIR),.)
+InstallDynamicModule($(LIBNAME),$(MODULEDIR)/dri,.)
#endif
DependTarget()
diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c
index b7fc70b79..a0d9cdf73 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c
@@ -78,6 +78,21 @@ static mgaContextPtr mgaCtx = 0;
mgaGlx_t mgaglx;
+/* These functions are accessed externally to the driver:
+ *
+ * XMesaInitDriver
+ * XMesaResetDriver
+ * XMesaCreateVisual
+ * XMesaDestroyVisual
+ * XMesaCreateContext
+ * XMesaDestroyContext
+ * XMesaCreateWindowBuffer
+ * XMesaCreatePixmapBuffer
+ * XMesaDestroyBuffer
+ * XMesaSwapBuffers
+ * XMesaMakeCurrent
+ *
+ */
GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
{
@@ -150,23 +165,21 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
mgaScreen->depthPitch = serverInfo->depthPitch;
- mgaScreen->agp_tex.handle = serverInfo->agp;
- mgaScreen->agp_tex.size = serverInfo->agpSize;
+ mgaScreen->agp.handle = serverInfo->agp;
+ mgaScreen->agp.size = serverInfo->agpSize;
if (drmMap(sPriv->fd,
- mgaScreen->agp_tex.handle,
- mgaScreen->agp_tex.size,
- (drmAddress *)&mgaScreen->agp_tex.map) != 0)
+ mgaScreen->agp.handle,
+ mgaScreen->agp.size,
+ (drmAddress *)&mgaScreen->agp.map) != 0)
{
Xfree(mgaScreen);
sPriv->private = NULL;
return GL_FALSE;
}
-
-
mgaScreen->textureOffset[MGA_CARD_HEAP] = serverInfo->textureOffset;
- mgaScreen->textureOffset[MGA_AGP_HEAP] = (mgaScreen->agp_tex.handle |
+ mgaScreen->textureOffset[MGA_AGP_HEAP] = (serverInfo->agpTextureOffset |
PDEA_pagpxfer_enable | 1);
/*
@@ -184,12 +197,17 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
serverInfo->logAgpTextureGranularity;
mgaScreen->texVirtual[MGA_CARD_HEAP] = (mgaScreen->sPriv->pFB +
- mgaScreen->textureOffset[0]);
- mgaScreen->texVirtual[MGA_AGP_HEAP] = mgaScreen->agp_tex.map;
+ serverInfo->textureOffset);
+ mgaScreen->texVirtual[MGA_AGP_HEAP] = (mgaScreen->agp.map +
+ serverInfo->agpTextureOffset);
mgaScreen->mAccess = serverInfo->mAccess;
+ /* For calculating setupdma addresses.
+ */
+ mgaScreen->dmaOffset = serverInfo->agpBufferOffset;
+
/*
fprintf(stderr, "\n\n\nbackOffset: %x pitch %x\n",
mgaScreen->backOffset,
@@ -199,7 +217,7 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
mgaScreen->Attrib = MGA_PF_565;
mgaScreen->bufs = drmMapBufs(sPriv->fd);
if (!mgaScreen->bufs) {
- drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);
+ /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
XFree(mgaScreen);
sPriv->private = NULL;
return GL_FALSE;
@@ -210,6 +228,7 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
memset(&mgaglx, 0, sizeof(mgaglx));
mgaDDFastPathInit();
+ mgaDDEltPathInit();
mgaDDTrifuncInit();
mgaDDSetupInit();
@@ -222,7 +241,7 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
void XMesaResetDriver(__DRIscreenPrivate *sPriv)
{
mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *) sPriv->private;
- drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);
+ /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
Xfree(mgaScreen);
sPriv->private = NULL;
}
@@ -481,4 +500,5 @@ void mgaGetLock( mgaContextPtr mmesa, GLuint flags )
}
+
#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h
index d563bd429..489b71836 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h
+++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h
@@ -28,7 +28,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/*
* Authors:
* Keith Whitwell <keithw@precisioninsight.com>
- * Daryll Strauss <daryll@precisioninsight.com> (Origninal tdfx driver).
*
*/
@@ -42,7 +41,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "dri_mesaint.h"
#include "dri_mesa.h"
#include "types.h"
-#include "xmesaP.h"
+#include "mgaregs.h"
+
+typedef struct {
+ drmHandle handle;
+ drmSize size;
+ char *map;
+} mgaRegion, *mgaRegionPtr;
typedef struct {
@@ -54,53 +59,69 @@ typedef struct {
int cpp; /* for front and back buffers */
int Attrib;
+ unsigned int mAccess;
- int frontOffset;
- int frontPitch;
- int backOffset;
- int backPitch;
+ unsigned int frontOffset;
+ unsigned int frontPitch;
+ unsigned int backOffset;
+ unsigned int backPitch;
- int depthOffset;
- int depthPitch;
+ unsigned int depthOffset;
+ unsigned int depthPitch;
int depthCpp;
- int textureOffset;
- int textureSize;
- int logTextureGranularity;
+ unsigned int dmaOffset;
+
+ unsigned int textureOffset[MGA_NR_TEX_HEAPS];
+ unsigned int textureSize[MGA_NR_TEX_HEAPS];
+ int logTextureGranularity[MGA_NR_TEX_HEAPS];
+ char *texVirtual[MGA_NR_TEX_HEAPS];
+
__DRIscreenPrivate *sPriv;
drmBufMapPtr bufs;
+ /* Maps the dma buffers as well as textures ?
+ */
+ mgaRegion agp;
+
} mgaScreenPrivate;
#include "mgalib.h"
-extern void mgaXMesaUpdateState( mgaContextPtr mmesa );
+extern void mgaGetLock( mgaContextPtr mmesa, GLuint flags );
extern void mgaEmitHwStateLocked( mgaContextPtr mmesa );
extern void mgaEmitScissorValues( mgaContextPtr mmesa, int box_nr, int emit );
-extern void mgaXMesaSetBackClipRects( mgaContextPtr mmesa );
-extern void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa );
+
+#define GET_DISPATCH_AGE( mmesa ) mmesa->sarea->last_dispatch
+#define GET_ENQUEUE_AGE( mmesa ) mmesa->sarea->last_enqueue
/* Lock the hardware and validate our state.
*/
-#define LOCK_HARDWARE( mmesa ) \
- do { \
- char __ret=0; \
- DRM_CAS(mmesa->driHwLock, mmesa->hHWContext, \
- (DRM_LOCK_HELD|mmesa->hHWContext), __ret); \
- if (__ret) { \
- drmGetLock(mmesa->driFd, mmesa->hHWContext, 0); \
- mgaXMesaUpdateState( mmesa ); \
- } \
+#define LOCK_HARDWARE( mmesa ) \
+ do { \
+ char __ret=0; \
+ DRM_CAS(mmesa->driHwLock, mmesa->hHWContext, \
+ (DRM_LOCK_HELD|mmesa->hHWContext), __ret); \
+ if (__ret) \
+ mgaGetLock( mmesa, 0 ); \
} while (0)
+/*
+ */
+#define LOCK_HARDWARE_QUIESCENT( mmesa ) do { \
+ LOCK_HARDWARE( mmesa ); \
+ mgaUpdateLock( mmesa, DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH ); \
+} while (0)
+
+
/* Unlock the hardware using the global current context
*/
-#define UNLOCK_HARDWARE(mmesa) \
+#define UNLOCK_HARDWARE(mmesa) \
DRM_UNLOCK(mmesa->driFd, mmesa->driHwLock, mmesa->hHWContext);
@@ -109,6 +130,8 @@ extern void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa );
#define REFRESH_DRAWABLE_INFO( mmesa ) \
do { \
LOCK_HARDWARE( mmesa ); \
+ mmesa->lastX = mmesa->drawX; \
+ mmesa->lastY = mmesa->drawY; \
UNLOCK_HARDWARE( mmesa ); \
} while (0)
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaeltpath.c b/xc/lib/GL/mesa/src/drv/mga/mgaeltpath.c
new file mode 100644
index 000000000..4751eb091
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgaeltpath.c
@@ -0,0 +1,457 @@
+/*
+ * GLX Hardware Device Driver for Matrox G400
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+
+#include "types.h"
+#include "enums.h"
+#include "cva.h"
+#include "vertices.h"
+#include "mmath.h"
+#include "xform.h"
+
+#include "mgalib.h"
+#include "mgapipeline.h"
+#include "mgatris.h"
+#include "mgastate.h"
+#include "mgavb.h"
+
+
+/* Always use a full-sized stride for vertices. [FIXME]
+ * Stride in the buffers must be a quadword multiple.
+ */
+#define BUFFER_STRIDE 12
+#define CLIP_STRIDE 10
+
+
+static void fire_elts( mgaContextPtr mmesa )
+{
+ LOCK_HARDWARE( mmesa );
+
+ /* Fire queued elements and discard that buffer if its contents
+ * won't be referenced by future elements.
+ */
+ if (mmesa->elt_buf) {
+ GLuint retain = (mmesa->elt_buf == mmesa->retained_buf);
+
+ if (mmesa->first_elt != mmesa->next_elt) {
+ mgaFireEltsLocked( mmesa,
+ ((GLuint)mmesa->first_elt -
+ (GLuint)mmesa->elt_buf->address),
+ ((GLuint)mmesa->next_elt -
+ (GLuint)mmesa->elt_buf->address),
+ !retain );
+ } else if (!retain)
+ mgaReleaseBufLocked( mmesa, mmesa->elt_buf );
+
+ mmesa->elt_buf = 0;
+ }
+ else if (mmesa->vertex_dma_buffer)
+ {
+ mgaFlushVerticesLocked( mmesa );
+ }
+
+ mgaGetEltBufLocked( mmesa );
+
+ UNLOCK_HARDWARE( mmesa );
+
+ mmesa->next_vert = (GLfloat *)((GLuint)mmesa->elt_buf->address +
+ mmesa->elt_buf->total -
+ BUFFER_STRIDE * sizeof(GLfloat));
+
+ mmesa->next_vert_phys = (mmesa->mgaScreen->dmaOffset +
+ mmesa->elt_buf->idx * MGA_DMA_BUF_SZ +
+ mmesa->elt_buf->total -
+ BUFFER_STRIDE * sizeof(GLfloat));
+
+ mmesa->first_elt = (GLuint *)mmesa->elt_buf->address;
+ mmesa->next_elt = (GLuint *)mmesa->elt_buf->address;
+
+}
+
+
+static void release_bufs( mgaContextPtr mmesa )
+{
+ if (mmesa->retained_buf && mmesa->retained_buf != mmesa->elt_buf)
+ {
+ LOCK_HARDWARE( mmesa );
+ if (mmesa->first_elt != mmesa->next_elt) {
+ mgaFireEltsLocked( mmesa,
+ ((GLuint)mmesa->first_elt -
+ (GLuint)mmesa->elt_buf->address),
+ ((GLuint)mmesa->next_elt -
+ (GLuint)mmesa->elt_buf->address),
+ 0 );
+
+ mmesa->first_elt = mmesa->next_elt;
+ }
+
+ mgaReleaseBufLocked( mmesa, mmesa->retained_buf );
+ UNLOCK_HARDWARE( mmesa );
+ }
+
+ mmesa->retained_buf = 0;
+}
+
+
+
+
+#define NEGATIVE(f) (f < 0)
+#define DIFFERENT_SIGNS(a,b) ((a*b) < 0)
+#define LINTERP( T, A, B ) ( (A) + (T) * ( (B) - (A) ) )
+
+
+#define INTERP_RGBA(t, out, a, b) { \
+ int i; \
+ for (i = 0; i < 4; i++) { \
+ GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR(a[i]); \
+ GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR(b[i]); \
+ GLfloat fo = LINTERP(t, fa, fb); \
+ FLOAT_COLOR_TO_UBYTE_COLOR(out[i], fo); \
+ } \
+}
+
+
+#define CLIP(SGN,V,PLANE) \
+if (mask & PLANE) { \
+ GLuint *indata = inlist[in]; \
+ GLuint *outdata = inlist[in ^= 1]; \
+ GLuint nr = n; \
+ GLfloat *J = verts[indata[nr-1]]; \
+ GLfloat dpJ = (SGN J[V]) + J[3]; \
+ \
+ for (i = n = 0 ; i < nr ; i++) { \
+ GLuint elt_i = indata[i]; \
+ GLfloat *I = verts[elt_i]; \
+ GLfloat dpI = (SGN I[V]) + I[3]; \
+ \
+ if (DIFFERENT_SIGNS(dpI, dpJ)) { \
+ GLfloat *O = verts[next_vert]; \
+ outdata[n++] = next_vert++; \
+ \
+ if (NEGATIVE(dpI)) { \
+ GLfloat t = dpI / (dpI - dpJ); \
+ interp(t, O, I, J); \
+ } \
+ else \
+ { \
+ GLfloat t = dpJ / (dpJ - dpI); \
+ interp(t, O, J, I); \
+ } \
+ } \
+ \
+ if (!NEGATIVE(dpI)) \
+ outdata[n++] = elt_i; \
+ \
+ J = I; \
+ dpJ = dpI; \
+ } \
+ \
+ if (n < 3) return; \
+}
+
+
+static void mga_tri_clip( mgaContextPtr mmesa,
+ struct vertex_buffer *VB,
+ GLuint *elt,
+ GLubyte mask )
+{
+ struct mga_elt_tab *tab = mmesa->elt_tab;
+ mga_interp_func interp = tab->interp;
+ GLuint inlist[2][VB_MAX_CLIPPED_VERTS];
+ GLuint in = 0;
+ GLuint n = 3, next_vert = 3;
+ GLuint i;
+ GLfloat verts[VB_MAX_CLIPPED_VERTS][CLIP_STRIDE];
+
+ /* Build temporary vertices in clipspace. This is the potential
+ * downside to this path.
+ */
+ tab->build_tri_verts( mmesa, VB, (GLfloat *)verts, elt );
+
+ inlist[0][0] = 0;
+ inlist[0][1] = 1;
+ inlist[0][2] = 2;
+
+ CLIP(-,0,CLIP_RIGHT_BIT);
+ CLIP(+,0,CLIP_LEFT_BIT);
+ CLIP(-,1,CLIP_TOP_BIT);
+ CLIP(+,1,CLIP_BOTTOM_BIT);
+ CLIP(-,2,CLIP_FAR_BIT);
+ CLIP(+,2,CLIP_NEAR_BIT);
+
+
+ {
+ GLuint *out = inlist[in];
+ GLuint space = (GLuint)mmesa->next_vert - (GLuint)mmesa->next_elt;
+
+ if (space < n * (BUFFER_STRIDE + 3) * sizeof(GLuint))
+ fire_elts(mmesa);
+
+ /* Project the new vertices and emit to dma buffers. Translate
+ * out values to physical addresses for setup dma.
+ */
+ tab->project_and_emit_verts( mmesa, (GLfloat *)verts, out, n );
+
+ /* Convert the planar polygon to a list of triangles and emit to
+ * elt buffers.
+ */
+ for (i = 2 ; i < n ; i++) {
+ mmesa->next_elt[0] = out[0];
+ mmesa->next_elt[1] = out[i-1];
+ mmesa->next_elt[2] = out[i];
+ mmesa->next_elt += 3;
+ }
+ }
+}
+
+
+
+
+/* Build a table of functions to clip each primitive type. These
+ * produce a list of elements in the appropriate 'reduced' primitive,
+ * ie (points, lines, triangles) containing all the clipped and
+ * unclipped primitives from the original list.
+ */
+
+#define INIT(x)
+
+#define TRI_THRESHOLD (3 * sizeof(GLuint))
+
+#define UNCLIPPED_VERT(x) (mmesa->first_vert_phys - x * BUFFER_STRIDE * 4)
+
+#define TRIANGLE( e2, e1, e0 ) \
+do { \
+ if ((GLuint)mmesa->next_vert - \
+ (GLuint)mmesa->next_elt < TRI_THRESHOLD) \
+ fire_elts(mmesa); \
+ mmesa->next_elt[0] = UNCLIPPED_VERT(e2); \
+ mmesa->next_elt[1] = UNCLIPPED_VERT(e1); \
+ mmesa->next_elt[2] = UNCLIPPED_VERT(e0); \
+ mmesa->next_elt+=3; \
+} while (0)
+
+#define CLIP_TRIANGLE( e2, e1, e0 ) \
+do { \
+ GLubyte ormask = mask[e2] | mask[e1] | mask[e0]; \
+ if (ormask == 0) { \
+ TRIANGLE( e2, e1, e0 ); \
+ } else if ((mask[e2] & mask[e1] & mask[e0]) == 0) { \
+ out[0] = e2; \
+ out[1] = e1; \
+ out[2] = e0; \
+ mga_tri_clip( mmesa, VB, out, ormask ); \
+ } \
+} while (0)
+
+#define LOCAL_VARS \
+ mgaContextPtr mmesa = MGA_CONTEXT( VB->ctx ); \
+ GLuint *elt = VB->EltPtr->data; \
+ GLuint out[VB_MAX_CLIPPED_VERTS]; \
+ GLubyte *mask = VB->ClipMask; \
+ (void) mask; (void) out; (void) elt; (void) mmesa;
+
+
+
+#define RENDER_POINTS(start, count)
+#define RENDER_LINE(i1, i0)
+#define RENDER_TRI(i2, i1, i0, pv, parity) \
+do { \
+ GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \
+ if (parity) e2 = elt[i1], e1 = elt[i2]; \
+ CLIP_TRIANGLE( e2, e1, e0 ); \
+} while (0)
+
+#define RENDER_QUAD(i3, i2, i1, i0, pv ) \
+ CLIP_TRIANGLE(elt[i3], elt[i2], elt[i0]); \
+ CLIP_TRIANGLE(elt[i2], elt[i1], elt[i0])
+
+#define TAG(x) mga_##x##_elt
+#include "render_tmp.h"
+
+
+
+#define LOCAL_VARS \
+ mgaContextPtr mmesa = MGA_CONTEXT( VB->ctx ); \
+ GLuint *elt = VB->EltPtr->data; \
+ (void) elt; (void) mmesa;
+
+#define RENDER_POINTS(start, count)
+#define RENDER_LINE(i1, i0)
+#define RENDER_TRI(i2, i1, i0, pv, parity) \
+do { \
+ GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \
+ if (parity) e2 = elt[i1], e1 = elt[i2]; \
+ TRIANGLE( e2, e1, e0 ); \
+} while (0)
+
+#define RENDER_QUAD(i3, i2, i1, i0, pv ) \
+ TRIANGLE(elt[i3], elt[i2], elt[i0]); \
+ TRIANGLE(elt[i2], elt[i1], elt[i0])
+
+#define TAG(x) mga_##x##_elt_unclipped
+#include "render_tmp.h"
+
+
+
+
+static void refresh_projection_matrix( GLcontext *ctx )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+ GLfloat *m = mmesa->device_matrix;
+ GLmatrix *mat = &ctx->Viewport.WindowMap;
+
+ REFRESH_DRAWABLE_INFO(mmesa);
+
+ m[MAT_SX] = mat->m[MAT_SX];
+ m[MAT_TX] = mat->m[MAT_TX] + mmesa->drawX + .5;
+ m[MAT_SY] = (- mat->m[MAT_SY]);
+ m[MAT_TY] = (- mat->m[MAT_TY]) + mmesa->driDrawable->h + mmesa->drawY - .5;
+ m[MAT_SZ] = mat->m[MAT_SZ] * (1.0 / 0x10000);
+ m[MAT_TZ] = mat->m[MAT_TZ] * (1.0 / 0x10000);
+}
+
+#define CLIP_UBYTE_B 0
+#define CLIP_UBYTE_G 1
+#define CLIP_UBYTE_R 2
+#define CLIP_UBYTE_A 3
+
+
+#define TYPE (0)
+#define TAG(x) x
+#include "mgaelttmp.h"
+
+#define TYPE (MGA_RGBA_BIT)
+#define TAG(x) x##_RGBA
+#include "mgaelttmp.h"
+
+#define TYPE (MGA_TEX0_BIT)
+#define TAG(x) x##_TEX0
+#include "mgaelttmp.h"
+
+#define TYPE (MGA_RGBA_BIT|MGA_TEX0_BIT)
+#define TAG(x) x##_RGBA_TEX0
+#include "mgaelttmp.h"
+
+#define TYPE (MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
+#define TAG(x) x##_RGBA_TEX0_TEX1
+#include "mgaelttmp.h"
+
+#define TYPE (MGA_TEX0_BIT|MGA_TEX1_BIT)
+#define TAG(x) x##_TEX0_TEX1
+#include "mgaelttmp.h"
+
+
+/* Very sparsely popluated array - fix the indices.
+ */
+static struct mga_elt_tab mgaEltTab[0x80];
+
+void mgaDDEltPathInit( void )
+{
+ mga_render_init_elt();
+ mga_render_init_elt_unclipped();
+
+ mga_init_eltpath( &mgaEltTab[0] );
+ mga_init_eltpath_RGBA( &mgaEltTab[MGA_RGBA_BIT] );
+ mga_init_eltpath_TEX0( &mgaEltTab[MGA_TEX0_BIT] );
+ mga_init_eltpath_RGBA_TEX0( &mgaEltTab[MGA_RGBA_BIT|MGA_TEX0_BIT] );
+ mga_init_eltpath_TEX0_TEX1( &mgaEltTab[MGA_TEX0_BIT|MGA_TEX1_BIT] );
+ mga_init_eltpath_RGBA_TEX0_TEX1( &mgaEltTab[MGA_RGBA_BIT|MGA_TEX0_BIT|
+ MGA_TEX1_BIT] );
+}
+
+#define VALID_SETUP (MGA_RGBA_BIT|MGA_TEX0_BIT|MGA_TEX1_BIT)
+
+
+
+/* Use a temporary array for device coordinates, so that we can easily
+ * tap into existing mesa assembly. Otherwise consider emitting
+ * device coordinates to dma buffers directly from the project/cliptest
+ * routine. (requires output stride, potential loss of writecombining
+ * efficiency?)
+ *
+ * This path is a lot closer to the standard vertex path in the
+ * initial stages than the original fastpath. A slightly more optimal
+ * path could be constructed, but would require us to write new
+ * assembly.
+ */
+void mgaDDEltPath( struct vertex_buffer *VB )
+{
+ GLcontext *ctx = VB->ctx;
+ GLenum prim = ctx->CVA.elt_mode;
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ struct mga_elt_tab *tab = &mgaEltTab[mmesa->setupindex & VALID_SETUP];
+
+ VB->ClipPtr = TransformRaw(&VB->Clip, &ctx->ModelProjectMatrix, VB->ObjPtr );
+
+ refresh_projection_matrix( ctx );
+
+ VB->ClipAndMask = ~0;
+ VB->ClipOrMask = 0;
+ VB->Projected = gl_clip_tab[VB->ClipPtr->size]( VB->ClipPtr,
+ &VB->Win,
+ VB->ClipMask,
+ &VB->ClipOrMask,
+ &VB->ClipAndMask );
+
+ if (VB->ClipAndMask)
+ return;
+
+ if (mmesa->vertex_dma_buffer)
+ mgaFlushVertices( mmesa );
+
+ if (mmesa->new_state)
+ mgaDDUpdateHwState( ctx );
+
+ /* Allocate a single buffer to hold unclipped vertices. All
+ * unclipped vertices must be contiguous.
+ */
+ if ((GLuint)mmesa->next_vert - (GLuint)mmesa->next_elt <
+ VB->Count * BUFFER_STRIDE * sizeof(GLuint))
+ fire_elts( mmesa );
+
+ mmesa->retained_buf = mmesa->elt_buf;
+
+ /* Emit unclipped vertices to the buffer.
+ */
+ tab->emit_unclipped_verts( VB );
+
+ /* Emit indices and clipped vertices to one or more buffers.
+ */
+ if (VB->ClipOrMask) {
+ mmesa->elt_tab = tab;
+ mga_render_tab_elt[prim]( VB, 0, VB->EltPtr->count, 0 );
+ } else
+ mga_render_tab_elt_unclipped[prim]( VB, 0, VB->EltPtr->count, 0 );
+
+ /* Send to hardware and release any retained buffers.
+ */
+ release_bufs( mmesa );
+
+ /* This indicates that there is no cached data to reuse.
+ */
+ VB->pipeline->data_valid = 0;
+ VB->pipeline->new_state = 0;
+}
+
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaelttmp.h b/xc/lib/GL/mesa/src/drv/mga/mgaelttmp.h
new file mode 100644
index 000000000..ce758a532
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/mga/mgaelttmp.h
@@ -0,0 +1,269 @@
+/*
+ * DRI Hardware Device Driver for G200/G400
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/* Buffers fill from high addresses down with vertices and from low
+ * addresses up with elements.
+ */
+
+
+/* Emit the bulk of the vertices to the first dma buffer. Leave
+ * empty slots for clipped vertices so that we can still address
+ * vertices by index.
+ */
+static void TAG(emit_unclipped_verts)( struct vertex_buffer *VB )
+{
+ GLuint i;
+ mgaContextPtr mmesa = MGA_CONTEXT(VB->ctx);
+ GLfloat *dev = VB->Projected->start;
+ GLubyte *color = VB->ColorPtr->start;
+ GLfloat *tex0_data = VB->TexCoordPtr[0]->start;
+ GLfloat *tex1_data = VB->TexCoordPtr[1]->start;
+ GLuint color_stride = VB->ColorPtr->stride;
+ GLuint tex0_stride = VB->TexCoordPtr[0]->stride;
+ GLuint tex1_stride = VB->TexCoordPtr[1]->stride;
+
+ GLfloat *f = mmesa->next_vert;
+ GLuint count = VB->Count;
+ GLubyte *clipmask = VB->ClipMask;
+
+ const GLfloat *m = mmesa->device_matrix;
+ const GLfloat sx = m[0], sy = m[5], sz = m[10];
+ const GLfloat tx = m[12], ty = m[13], tz = m[14];
+
+ mmesa->retained_buf = mmesa->elt_buf;
+ mmesa->first_vert_phys = mmesa->next_vert_phys;
+
+ for (i = 0 ; i < count ; f -= BUFFER_STRIDE, i++)
+ {
+ if (!clipmask[i])
+ {
+ f[0] = sx * dev[0] + tx;
+ f[1] = sy * dev[1] + ty;
+ f[2] = sz * dev[2] + tz;
+ f[3] = dev[3];
+
+ if (TYPE & MGA_RGBA_BIT) {
+#if defined(USE_X86_ASM)
+ __asm__ (
+ "movl (%%edx),%%eax \n"
+ "bswap %%eax \n"
+ "rorl $8,%%eax \n"
+ "movl %%eax,16(%%edi) \n"
+ :
+ : "d" (color), "D" (f)
+ : "%eax" );
+#else
+ GLubyte *b = (GLubyte *)&f[4];
+ b[CLIP_UBYTE_B] = color[2];
+ b[CLIP_UBYTE_G] = color[1];
+ b[CLIP_UBYTE_R] = color[0];
+ b[CLIP_UBYTE_A] = color[3];
+#endif
+ }
+
+ if (TYPE & MGA_TEX0_BIT) {
+/* fprintf(stderr, "i %d tex0 %f, %f\n", i, */
+/* tex0_data[0], tex0_data[1]); */
+ *(int*)&f[6] = *(int*)&tex0_data[0];
+ *(int*)&f[7] = *(int*)&tex0_data[1];
+ }
+
+ if (TYPE & MGA_TEX1_BIT) {
+ *(int*)&f[8] = *(int*)&tex1_data[0];
+ *(int*)&f[9] = *(int*)&tex1_data[1];
+ }
+ }
+
+ STRIDE_F(dev, 16);
+ if (TYPE & MGA_RGBA_BIT) color += color_stride;
+ if (TYPE & MGA_TEX0_BIT) STRIDE_F(tex0_data, tex0_stride);
+ if (TYPE & MGA_TEX1_BIT) STRIDE_F(tex1_data, tex1_stride);
+ }
+
+ mmesa->next_vert = f;
+ mmesa->next_vert_phys -= count * BUFFER_STRIDE * sizeof(GLuint);
+}
+
+
+/* Build three temporary clipspace vertex for clipping a triangle.
+ * Recreate from the VB data rather than trying to read back from
+ * uncached memory.
+ */
+static void TAG(build_tri_verts)( mgaContextPtr mmesa,
+ struct vertex_buffer *VB,
+ GLfloat *O,
+ GLuint *elt )
+{
+ int i;
+
+ for (i = 0 ; i < 3 ; i++, O += CLIP_STRIDE) {
+ GLfloat *clip = VB->Clip.start + elt[i]*4;
+
+ O[0] = clip[0];
+ O[1] = clip[1];
+ O[2] = clip[2];
+ O[3] = clip[3];
+
+ if (TYPE & MGA_RGBA_BIT) {
+ GLubyte *col = VEC_ELT(VB->ColorPtr, GLubyte, elt[i]);
+ GLubyte *b = (GLubyte *)&O[4];
+ b[CLIP_UBYTE_R] = col[0];
+ b[CLIP_UBYTE_G] = col[1];
+ b[CLIP_UBYTE_B] = col[2];
+ b[CLIP_UBYTE_A] = col[3];
+ }
+
+ if (0)
+ fprintf(stderr,
+ "build_tri_vert elt[%d]: %d phys: %x (first_phys %x elt_buf %x\n",
+ i, elt[i], UNCLIPPED_VERT(elt[i]),
+ mmesa->first_vert_phys, (GLuint)mmesa->elt_buf);
+
+ *(GLuint *)&O[5] = UNCLIPPED_VERT(elt[i]);
+
+ if (TYPE & MGA_TEX0_BIT) {
+ GLfloat *tex0_data = VEC_ELT(VB->TexCoordPtr[0], GLfloat, elt[i]);
+ *(int*)&O[6] = *(int*)&tex0_data[0];
+ *(int*)&O[7] = *(int*)&tex0_data[1];
+ }
+
+ if (TYPE & MGA_TEX1_BIT) {
+ GLfloat *tex1_data = VEC_ELT(VB->TexCoordPtr[1], GLfloat, elt[i]);
+ *(int*)&O[8] = *(int*)&tex1_data[0];
+ *(int*)&O[9] = *(int*)&tex1_data[1];
+ }
+ }
+}
+
+
+/* Interpolate between two of the vertices constructed above.
+ */
+static void TAG(interp)( GLfloat t,
+ GLfloat *O,
+ const GLfloat *I,
+ const GLfloat *J )
+{
+ O[0] = LINTERP(t, I[0], J[0]);
+ O[1] = LINTERP(t, I[1], J[1]);
+ O[2] = LINTERP(t, I[2], J[2]);
+ O[3] = LINTERP(t, I[3], J[3]);
+
+ if (TYPE & MGA_RGBA_BIT) {
+ INTERP_RGBA(t,
+ ((GLubyte *)&(O[4])),
+ ((GLubyte *)&(I[4])),
+ ((GLubyte *)&(J[4])));
+ }
+
+ if (0) fprintf(stderr, "setting 0x%x to ~0\n", (GLuint)&O[5]);
+
+ *(GLuint *)&O[5] = ~0; /* note that this is a new vertex */
+
+ if (TYPE & MGA_TEX0_BIT) {
+ O[6] = LINTERP(t, I[6], J[6]);
+ O[7] = LINTERP(t, I[7], J[7]);
+ }
+
+ if (TYPE & MGA_TEX1_BIT) {
+ O[8] = LINTERP(t, I[8], J[8]);
+ O[9] = LINTERP(t, I[9], J[9]);
+ }
+}
+
+
+
+/* When clipping is complete, scan the final vertex list and emit any
+ * new ones to dma buffers. Update the element list to a format
+ * suitable for sending to hardware.
+ */
+static void TAG(project_and_emit_verts)( mgaContextPtr mmesa,
+ const GLfloat *verts,
+ GLuint *elt,
+ int nr)
+{
+
+ GLfloat *O = mmesa->next_vert;
+ GLuint phys = mmesa->next_vert_phys;
+
+ const GLfloat *m = mmesa->device_matrix;
+ const GLfloat sx = m[0], sy = m[5], sz = m[10];
+ const GLfloat tx = m[12], ty = m[13], tz = m[14];
+ GLuint i;
+
+ for (i = 0 ; i < nr ; i++) {
+ const GLfloat *I = &verts[elt[i] * CLIP_STRIDE];
+ GLuint tmp = *(GLuint *)&I[5];
+
+ if (0) fprintf(stderr, "elt[%d] (tmp 0x%x %d) %d --> ", i, (GLuint)&I[5],
+ tmp, elt[i]);
+
+
+ if ((elt[i] = tmp) == ~0)
+ {
+ GLfloat oow = 1.0/I[3];
+
+ elt[i] = phys;
+ phys -= BUFFER_STRIDE * sizeof(GLuint);
+
+ O[0] = sx * I[0] * oow + tx;
+ O[1] = sy * I[1] * oow + ty;
+ O[2] = sz * I[2] * oow + tz;
+ O[3] = oow;
+
+ if (TYPE & MGA_RGBA_BIT) {
+ *(int*)&O[4] = *(int*)&I[4];
+ }
+
+ if (TYPE & MGA_TEX0_BIT) {
+ *(int*)&O[6] = *(int*)&I[6];
+ *(int*)&O[7] = *(int*)&I[7];
+ }
+
+ if (TYPE & MGA_TEX1_BIT) {
+ *(int*)&O[8] = *(int*)&I[8];
+ *(int*)&O[9] = *(int*)&I[9];
+ }
+
+ O -= BUFFER_STRIDE;
+ }
+ if (0) fprintf(stderr, "0x%x\n", elt[i]);
+ }
+
+ mmesa->next_vert = O;
+ mmesa->next_vert_phys = phys;
+}
+
+
+
+static void TAG(mga_init_eltpath)( struct mga_elt_tab *tab )
+{
+ tab->emit_unclipped_verts = TAG(emit_unclipped_verts);
+ tab->build_tri_verts = TAG(build_tri_verts);
+ tab->interp = TAG(interp);
+ tab->project_and_emit_verts = TAG(project_and_emit_verts);
+}
+
+#undef TYPE
+#undef TAG
+#undef STRIDE
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c b/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c
index cd316e162..73a939b74 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgafastpath.c
@@ -488,6 +488,16 @@ void mgaDDFastPath( struct vertex_buffer *VB )
gl_prepare_arrays_cva( VB ); /* still need this */
+ if (gl_reduce_prim[prim] == GL_TRIANGLES &&
+ VB->Count < (MGA_DMA_BUF_SZ / 48) &&
+ (ctx->ModelProjectMatrix.flags & (MAT_FLAG_GENERAL|
+ MAT_FLAG_PERSPECTIVE)) &&
+ mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G400)
+ {
+ mgaDDEltPath( VB );
+ return;
+ }
+
/* Reserve enough space for the pathological case.
*/
if (VB->EltPtr->count * 12 > MGA_DRIVER_DATA(VB)->size) {
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h b/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h
index 43caddcac..683640409 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h
+++ b/xc/lib/GL/mesa/src/drv/mga/mgafasttmp.h
@@ -39,7 +39,6 @@ static void TAG(mga_setup_full)( struct vertex_buffer *VB, GLuint do_cliptest )
const GLfloat * const m = ctx->ModelProjectMatrix.m;
GLuint start = VB->CopyStart;
GLuint count = VB->Count;
- GLuint i;
gl_xform_points3_v16_general(MGA_DRIVER_DATA(VB)->verts[start].f,
m,
@@ -71,26 +70,63 @@ static void TAG(mga_setup_full)( struct vertex_buffer *VB, GLuint do_cliptest )
GLuint tex1_stride = VB->TexCoordPtr[1]->stride;
GLfloat *f = MGA_DRIVER_DATA(VB)->verts[start].f;
-
- for (i = start ; i < count ; i++, f += 16) {
+ GLfloat *end = f+(16*(count-start));
+ while (f != end) {
if (TYPE & MGA_RGBA_BIT) {
+#if defined(USE_X86_ASM)
+ __asm__ (
+ "movl (%%edx),%%eax \n"
+ "bswap %%eax \n"
+ "rorl $8,%%eax \n"
+ "movl %%eax,16(%%edi) \n"
+ :
+ : "d" (color), "D" (f)
+ : "%eax" );
+#else
+ GLubyte *col = color;
GLubyte *b = (GLubyte *)&f[CLIP_UBYTE_COLOR];
- GLubyte *col = color; color += color_stride;
- b[CLIP_UBYTE_R] = col[0];
- b[CLIP_UBYTE_G] = col[1];
b[CLIP_UBYTE_B] = col[2];
+ b[CLIP_UBYTE_G] = col[1];
+ b[CLIP_UBYTE_R] = col[0];
b[CLIP_UBYTE_A] = col[3];
+#endif
}
if (TYPE & MGA_TEX0_BIT) {
- f[CLIP_S0] = tex0_data[0];
- f[CLIP_T0] = tex0_data[1];
- STRIDE_F(tex0_data, tex0_stride);
+#if defined (USE_X86_ASM)
+ __asm__ (
+ "movl (%%ecx), %%eax \n"
+ "movl %%eax, 24(%%edi) \n"
+ "movl 4(%%ecx), %%eax \n"
+ "movl %%eax, 28(%%edi)"
+ :
+ : "c" (tex0_data), "D" (f)
+ : "%eax");
+#else
+ *(unsigned int *)(f+CLIP_S0) = *(unsigned int *)tex0_data;
+ *(unsigned int *)(f+CLIP_T0) = *(unsigned int *)(tex0_data+1);
+#endif
}
if (TYPE & MGA_TEX1_BIT) {
- f[CLIP_S1] = tex1_data[0];
- f[CLIP_T1] = tex1_data[1];
- STRIDE_F(tex1_data, tex1_stride);
+ /* Hits a second cache line.
+ */
+#if defined (USE_X86_ASM)
+ __asm__ (
+ "movl (%%esi), %%eax \n"
+ "movl %%eax, 32(%%edi) \n"
+ "movl 4(%%esi), %%eax \n"
+ "movl %%eax, 36(%%edi)"
+ :
+ : "S" (tex1_data), "D" (f)
+ : "%eax");
+#else
+ *(unsigned int *)(f+CLIP_S1) = *(unsigned int *)tex1_data;
+ *(unsigned int *)(f+CLIP_T1) = *(unsigned int *)(tex1_data+1);
+#endif
}
+ if(TYPE & MGA_RGBA_BIT)color += color_stride;
+ if(TYPE & MGA_TEX0_BIT)STRIDE_F(tex0_data, tex0_stride);
+ if(TYPE & MGA_TEX1_BIT)STRIDE_F(tex1_data, tex1_stride);
+ f += 16;
}
}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c
index c1819924d..640849e3f 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c
@@ -14,114 +14,137 @@
#include "mgalog.h"
#include "mgavb.h"
#include "mgatris.h"
+#include "mgabuffers.h"
+
#include "drm.h"
#include <sys/ioctl.h>
+#define DEPTH_SCALE 65535.0F
+
static void mga_iload_dma_ioctl(mgaContextPtr mmesa,
- int x1, int y1, int x2, int y2,
- unsigned long dest, unsigned int maccess)
+ unsigned long dest,
+ int length)
{
int retcode;
drm_mga_iload_t iload;
- drmBufPtr buf = mmesa->dma_buffer;
+ drmBufPtr buf = mmesa->iload_buffer;
iload.idx = buf->idx;
iload.destOrg = dest;
- iload.mAccess = maccess;
- iload.texture.x1 = x1;
- iload.texture.y1 = y1;
- iload.texture.y2 = x2;
- iload.texture.x2 = y2;
+ iload.length = length;
+
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "DRM_IOCTL_MGA_ILOAD idx %d dst %x length %d\n",
+ iload.idx, iload.destOrg, iload.length);
+
if ((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_ILOAD, &iload))) {
printf("send iload retcode = %d\n", retcode);
exit(1);
}
-}
+ mmesa->iload_buffer = 0;
+
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "finished iload dma put\n");
+
+}
-static void mga_vertex_dma_ioctl(mgaContextPtr mmesa)
+int mgaUpdateLock( mgaContextPtr mmesa, drmLockFlags flags )
{
- int retcode;
- int size = MGA_DMA_BUF_SZ;
- drmDMAReq dma;
- drmBufPtr buf = mmesa->dma_buffer;
+ drm_lock_t lock;
+
+ lock.flags = 0;
- dma.context = mmesa->hHWContext;
- dma.send_count = 1;
- dma.send_list = &buf->idx;
- dma.send_sizes = &size;
- dma.flags = DRM_DMA_WAIT;
- dma.request_count = 0;
- dma.request_size = 0;
- dma.request_list = 0;
- dma.request_sizes = 0;
-
- if ((retcode = drmDMA(mmesa->driFd, &dma))) {
- printf("send iload retcode = %d\n", retcode);
- exit(1);
+ if (mmesa->sarea->last_quiescent != mmesa->sarea->last_enqueue &&
+ flags & DRM_LOCK_QUIESCENT) {
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "mgaLockQuiescent\n");
+ lock.flags |= _DRM_LOCK_QUIESCENT;
+ }
+
+ if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH;
+ if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL;
+
+ if (!lock.flags)
+ return 0;
+
+ if(ioctl(mmesa->driFd, DRM_IOCTL_MGA_FLUSH, &lock)) {
+ fprintf(stderr, "Lockupdate failed\n");
+ return -1;
}
+
+ if(flags & DRM_LOCK_QUIESCENT)
+ mmesa->sarea->last_quiescent = mmesa->sarea->last_enqueue;
+
+ return 0;
}
-
-static void mga_get_buffer_ioctl( mgaContextPtr mmesa )
+static drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa )
{
int idx = 0;
int size = 0;
drmDMAReq dma;
int retcode;
+ drmBufPtr buf;
- fprintf(stderr, "Getting dma buffer\n");
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "Getting dma buffer\n");
dma.context = mmesa->hHWContext;
dma.send_count = 0;
dma.send_list = NULL;
dma.send_sizes = NULL;
- dma.flags = DRM_DMA_WAIT;
+ dma.flags = 0;
dma.request_count = 1;
dma.request_size = MGA_DMA_BUF_SZ;
dma.request_list = &idx;
dma.request_sizes = &size;
-
- if ((retcode = drmDMA(mmesa->driFd, &dma))) {
- fprintf(stderr, "request drmDMA retcode = %d\n", retcode);
- exit(1);
- }
+ dma.granted_count = 0;
- mmesa->dma_buffer = &mmesa->mgaScreen->bufs->list[idx];
-}
-static void mga_swap_ioctl( mgaContextPtr mmesa )
-{
- int retcode;
- drm_mga_swap_t swap;
-
- if((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_SWAP, &swap))) {
- printf("send swap retcode = %d\n", retcode);
- exit(1);
- }
-}
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "drmDMA (get) ctx %d count %d size 0x%x\n",
+ dma.context, dma.request_count,
+ dma.request_size);
+ while (1) {
+ retcode = drmDMA(mmesa->driFd, &dma);
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "retcode %d sz %d idx %d count %d\n",
+ retcode,
+ dma.request_sizes[0],
+ dma.request_list[0],
+ dma.granted_count);
-static void mga_clear_ioctl( mgaContextPtr mmesa, int flags, int col, int zval )
-{
- int retcode;
- drm_mga_clear_t clear;
-
- clear.flags = flags;
- clear.clear_color = col;
- clear.clear_depth = zval;
-
- if((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_CLEAR, &clear))) {
- printf("send clear retcode = %d\n", retcode);
- exit(1);
+ if (retcode == 0 &&
+ dma.request_sizes[0] &&
+ dma.granted_count)
+ break;
+
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "\n\nflush");
+ mgaUpdateLock( mmesa, DRM_LOCK_FLUSH );
}
-}
+ buf = &(mmesa->mgaScreen->bufs->list[idx]);
+ buf->used = 0;
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr,
+ "drmDMA (get) returns size[0] 0x%x idx[0] %d\n"
+ "dma_buffer now: buf idx: %d size: %d used: %d\n",
+ dma.request_sizes[0], dma.request_list[0],
+ buf->idx, buf->total,
+ buf->used);
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "finished getbuffer\n");
+
+ return buf;
+}
@@ -130,52 +153,59 @@ GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- GLuint c = mmesa->ClearColor;
- mgaUI32 zval = (mgaUI32) (ctx->Depth.Clear * DEPTH_SCALE);
__DRIdrawablePrivate *dPriv = mmesa->driDrawable;
- int flags = 0;
+ const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
+ drm_mga_clear_t clear;
+ int retcode;
int i;
+ static int nrclears;
- mgaMsg( 10, "mgaClear( %i, %i, %i, %i, %i )\n",
- mask, x, y, width, height );
-
+ if (0) fprintf(stderr, "clear %d: %d,%d %dx%d\n", all,cx,cy,cw,ch);
- mgaFlushVertices( mmesa );
+ clear.flags = 0;
+ clear.clear_color = mmesa->ClearColor;
+ clear.clear_depth = (mgaUI32) (ctx->Depth.Clear * DEPTH_SCALE);
+ FLUSH_BATCH( mmesa );
+
+ if ((mask & DD_FRONT_LEFT_BIT) && colorMask == ~0) {
+ clear.flags |= MGA_FRONT;
+ mask &= ~DD_FRONT_LEFT_BIT;
+ }
- if (mask & GL_COLOR_BUFFER_BIT) {
- if (ctx->Color.DriverDrawBuffer == GL_FRONT_LEFT) {
- flags |= MGA_CLEAR_FRONT;
- mask &= ~GL_COLOR_BUFFER_BIT;
- } else if (ctx->Color.DriverDrawBuffer == GL_BACK_LEFT) {
- flags |= MGA_CLEAR_BACK;
- mask &= ~GL_COLOR_BUFFER_BIT;
- }
+ if ((mask & DD_BACK_LEFT_BIT) && colorMask == ~0) {
+ clear.flags |= MGA_BACK;
+ mask &= ~DD_BACK_LEFT_BIT;
}
- if ((flags & GL_DEPTH_BUFFER_BIT) && ctx->Depth.Mask) {
- flags |= MGA_CLEAR_DEPTH;
- mask &= ~GL_DEPTH_BUFFER_BIT;
+ if ((mask & DD_DEPTH_BIT) && ctx->Depth.Mask) {
+ clear.flags |= MGA_DEPTH;
+ mask &= ~DD_DEPTH_BIT;
}
- if (!flags)
+ if (!clear.flags)
return mask;
LOCK_HARDWARE( mmesa );
-
+
+ if (mmesa->dirty_cliprects)
+ mgaUpdateRects( mmesa, (MGA_FRONT|MGA_BACK));
+
/* flip top to bottom */
cy = dPriv->h-cy-ch;
cx += mmesa->drawX;
cy += mmesa->drawY;
- for (i = 0 ; i < dPriv->numClipRects ; ) {
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "Clear, bufs %x nbox %d\n",
+ (int)clear.flags, (int)mmesa->numClipRects);
- /* Use the cliprects for the current draw buffer
- */
+ for (i = 0 ; i < mmesa->numClipRects ; )
+ {
int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, mmesa->numClipRects);
XF86DRIClipRectRec *box = mmesa->pClipRects;
- xf86drmClipRectRec *b = mmesa->sarea->boxes;
- mmesa->sarea->nbox = nr - i;
+ drm_clip_rect_t *b = mmesa->sarea->boxes;
+ int n = 0;
if (!all) {
for ( ; i < nr ; i++) {
@@ -196,16 +226,37 @@ GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
b->x2 = x + w;
b->y2 = y + h;
b++;
+ n++;
}
} else {
- for ( ; i < nr ; i++)
- *b++ = *(xf86drmClipRectRec *)&box[i];
+ for ( ; i < nr ; i++) {
+ *b++ = *(drm_clip_rect_t *)&box[i];
+ n++;
+ }
}
- mga_clear_ioctl( mmesa, mask, c, zval );
+
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr,
+ "DRM_IOCTL_MGA_CLEAR flag 0x%x color %x depth %x nbox %d\n",
+ clear.flags, clear.clear_color,
+ clear.clear_depth, mmesa->sarea->nbox);
+
+
+ mmesa->sarea->nbox = n;
+
+ retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_CLEAR, &clear);
+ if (retcode) {
+ printf("send clear retcode = %d\n", retcode);
+ exit(1);
+ }
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "finished clear %d\n", ++nrclears);
}
UNLOCK_HARDWARE( mmesa );
+ mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
+
return mask;
}
@@ -218,50 +269,61 @@ GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
void mgaSwapBuffers( mgaContextPtr mmesa )
{
__DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+ XF86DRIClipRectPtr pbox;
+ int nbox;
+ drm_mga_swap_t swap;
+ static int nrswaps;
+ int retcode;
int i;
+ int tmp;
- mgaFlushVertices( mmesa );
- LOCK_HARDWARE( mmesa );
- {
- /* Use the frontbuffer cliprects
- */
- XF86DRIClipRectPtr pbox = dPriv->pClipRects;
- int nbox = dPriv->numClipRects;
+ FLUSH_BATCH( mmesa );
- for (i = 0 ; i < nbox ; )
- {
- int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
- XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)mmesa->sarea->boxes;
- mmesa->sarea->nbox = nr - i;
+ LOCK_HARDWARE( mmesa );
+
+ /* Use the frontbuffer cliprects
+ */
+ if (mmesa->dirty_cliprects & MGA_FRONT)
+ mgaUpdateRects( mmesa, MGA_FRONT );
+
- for ( ; i < nr ; i++)
- *b++ = pbox[i];
-
- mga_swap_ioctl( mmesa );
- }
- }
+ pbox = dPriv->pClipRects;
+ nbox = dPriv->numClipRects;
+ if (0) fprintf(stderr, "swap, nbox %d\n", nbox);
-#if 1
- UNLOCK_HARDWARE(mmesa);
-#else
+ for (i = 0 ; i < nbox ; )
{
- last_enqueue = mmesa->sarea->lastEnqueue;
- last_dispatch = mmesa->sarea->lastDispatch;
- UNLOCK_HARDWARE;
+ int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
+ XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)mmesa->sarea->boxes;
+
+ mmesa->sarea->nbox = nr - i;
+
+ for ( ; i < nr ; i++)
+ *b++ = pbox[i];
- /* Throttle runaway apps - there should be an easier way to sleep
- * on dma without locking out the rest of the system!
- */
- if (mmesa->lastSwap > last_dispatch) {
- drmGetLock(mmesa->driFd, mmesa->hHWContext, DRM_LOCK_QUIESCENT);
- DRM_UNLOCK(mmesa->driFd, mmesa->driHwLock, mmesa->hHWContext);
+ if (0)
+ fprintf(stderr, "DRM_IOCTL_MGA_SWAP\n");
+
+ if((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_SWAP, &swap))) {
+ printf("send swap retcode = %d\n", retcode);
+ exit(1);
}
- mmesa->lastSwap = last_enqueue;
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "finished swap %d\n", ++nrswaps);
}
-#endif
+
+ tmp = GET_ENQUEUE_AGE(mmesa);
+
+ UNLOCK_HARDWARE( mmesa );
+
+ if (GET_DISPATCH_AGE(mmesa) < mmesa->lastSwap)
+ mgaWaitAge(mmesa, mmesa->lastSwap);
+
+ mmesa->lastSwap = tmp;
+ mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
}
@@ -269,13 +331,165 @@ void mgaSwapBuffers( mgaContextPtr mmesa )
*/
void mgaDDFinish( GLcontext *ctx )
{
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- drmGetLock(mmesa->driFd, mmesa->hHWContext, DRM_LOCK_QUIESCENT);
- DRM_UNLOCK(mmesa->driFd, mmesa->driHwLock, mmesa->hHWContext);
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+ FLUSH_BATCH( mmesa );
+
+ if (mmesa->sarea->last_quiescent != mmesa->sarea->last_enqueue) {
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "mgaRegetLockQuiescent\n");
+
+ LOCK_HARDWARE( mmesa );
+ mgaUpdateLock( mmesa, DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH);
+ UNLOCK_HARDWARE( mmesa );
+
+ mmesa->sarea->last_quiescent = mmesa->sarea->last_enqueue;
+ }
+}
+
+void mgaWaitAgeLocked( mgaContextPtr mmesa, int age )
+{
+ if (GET_DISPATCH_AGE(mmesa) < age) {
+ if (0) fprintf(stderr, "\n\n\nmgaWaitAgeLocked\n");
+ mgaUpdateLock( mmesa, DRM_LOCK_FLUSH );
+ }
+}
+
+
+void mgaWaitAge( mgaContextPtr mmesa, int age )
+{
+ if (GET_DISPATCH_AGE(mmesa) < age) {
+ LOCK_HARDWARE(mmesa);
+ if (GET_DISPATCH_AGE(mmesa) < age) {
+ if (0) fprintf(stderr, "\n\n\nmgaWaitAge\n");
+ mgaUpdateLock( mmesa, DRM_LOCK_FLUSH );
+ }
+ UNLOCK_HARDWARE(mmesa);
+ }
+}
+
+
+static int intersect_rect( drm_clip_rect_t *out,
+ drm_clip_rect_t *a,
+ drm_clip_rect_t *b )
+{
+ *out = *a;
+ if (b->x1 > out->x1) out->x1 = b->x1;
+ if (b->y1 > out->y1) out->y1 = b->y1;
+ if (b->x2 < out->x2) out->x2 = b->x2;
+ if (b->y2 < out->y2) out->y2 = b->y2;
+ if (out->x1 >= out->x2) return 0;
+ if (out->y1 >= out->y2) return 0;
+ return 1;
+}
+
+
+
+
+static void age_mmesa( mgaContextPtr mmesa, int age )
+{
+ if (mmesa->CurrentTexObj[0]) mmesa->CurrentTexObj[0]->age = age;
+ if (mmesa->CurrentTexObj[1]) mmesa->CurrentTexObj[1]->age = age;
}
+void mgaFlushVerticesLocked( mgaContextPtr mmesa )
+{
+ drm_clip_rect_t *pbox = (drm_clip_rect_t *)mmesa->pClipRects;
+ int nbox = mmesa->numClipRects;
+ drmBufPtr buffer = mmesa->vertex_dma_buffer;
+ drm_mga_vertex_t vertex;
+ int i;
+
+ mmesa->vertex_dma_buffer = 0;
+
+ if (!buffer)
+ return;
+
+ if (mmesa->dirty_cliprects & mmesa->draw_buffer)
+ mgaUpdateRects( mmesa, mmesa->draw_buffer );
+
+ if (mmesa->dirty & ~MGA_UPLOAD_CLIPRECTS)
+ mgaEmitHwStateLocked( mmesa );
+
+ /* FIXME: Workaround bug in kernel module.
+ */
+ mmesa->sarea->dirty |= MGA_UPLOAD_CTX;
+
+ /* FIXME: dstorg bug
+ */
+ if (0)
+ if (mmesa->lastX != mmesa->drawX || mmesa->lastY != mmesa->drawY)
+ fprintf(stderr, "****** last: %d,%d current: %d,%d\n",
+ mmesa->lastX, mmesa->lastY,
+ mmesa->drawX, mmesa->drawY);
+
+ vertex.idx = buffer->idx;
+ vertex.used = buffer->used;
+ vertex.discard = 0;
+
+ if (!nbox)
+ vertex.used = 0;
+
+ if (nbox >= MGA_NR_SAREA_CLIPRECTS)
+ mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
+
+ if (!vertex.used || !(mmesa->dirty & MGA_UPLOAD_CLIPRECTS))
+ {
+ if (nbox == 1)
+ mmesa->sarea->nbox = 0;
+ else
+ mmesa->sarea->nbox = nbox;
+
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "Firing vertex -- case a nbox %d\n", nbox);
+
+ vertex.discard = 1;
+ ioctl(mmesa->driFd, DRM_IOCTL_MGA_VERTEX, &vertex);
+ age_mmesa(mmesa, mmesa->sarea->last_enqueue);
+ }
+ else
+ {
+ for (i = 0 ; i < nbox ; )
+ {
+ int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, nbox);
+ drm_clip_rect_t *b = mmesa->sarea->boxes;
+
+ if (mmesa->scissor) {
+ mmesa->sarea->nbox = 0;
+
+ for ( ; i < nr ; i++) {
+ *b = pbox[i];
+ if (intersect_rect(b, b, &mmesa->scissor_rect)) {
+ mmesa->sarea->nbox++;
+ b++;
+ }
+ }
+
+ /* Culled?
+ */
+ if (!mmesa->sarea->nbox) {
+ if (nr < nbox) continue;
+ vertex.used = 0;
+ }
+ } else {
+ mmesa->sarea->nbox = nr - i;
+ for ( ; i < nr ; i++)
+ *b++ = pbox[i];
+ }
+
+ /* Finished with the buffer?
+ */
+ if (nr == nbox)
+ vertex.discard = 1;
+ mmesa->sarea->dirty |= MGA_UPLOAD_CLIPRECTS;
+ ioctl(mmesa->driFd, DRM_IOCTL_MGA_VERTEX, &vertex);
+ age_mmesa(mmesa, mmesa->sarea->last_enqueue);
+ }
+ }
+ mmesa->dirty &= ~MGA_UPLOAD_CLIPRECTS;
+}
void mgaFlushVertices( mgaContextPtr mmesa )
{
@@ -284,38 +498,221 @@ void mgaFlushVertices( mgaContextPtr mmesa )
UNLOCK_HARDWARE( mmesa );
}
+void mgaFlushEltsLocked( mgaContextPtr mmesa )
+{
+ if (mmesa->first_elt != mmesa->next_elt) {
+ mgaFireEltsLocked( mmesa,
+ ((GLuint)mmesa->first_elt -
+ (GLuint)mmesa->elt_buf->address),
+ ((GLuint)mmesa->next_elt -
+ (GLuint)mmesa->elt_buf->address),
+ 0 );
+ mmesa->first_elt = mmesa->next_elt;
+ }
+}
-void mgaFlushVerticesLocked( mgaContextPtr mmesa )
+void mgaFlushElts( mgaContextPtr mmesa )
+{
+ LOCK_HARDWARE( mmesa );
+ mgaFlushEltsLocked( mmesa );
+ UNLOCK_HARDWARE( mmesa );
+}
+
+
+mgaUI32 *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords )
+{
+ int bytes = dwords * 4;
+ mgaUI32 *head;
+
+ if (!mmesa->vertex_dma_buffer) {
+ LOCK_HARDWARE( mmesa );
+
+ if (mmesa->first_elt != mmesa->next_elt)
+ mgaFlushEltsLocked(mmesa);
+
+ mmesa->vertex_dma_buffer = mga_get_buffer_ioctl( mmesa );
+ UNLOCK_HARDWARE( mmesa );
+ } else if (mmesa->vertex_dma_buffer->used + bytes >
+ mmesa->vertex_dma_buffer->total) {
+ LOCK_HARDWARE( mmesa );
+ mgaFlushVerticesLocked( mmesa );
+ mmesa->vertex_dma_buffer = mga_get_buffer_ioctl( mmesa );
+ UNLOCK_HARDWARE( mmesa );
+ }
+
+ head = (mgaUI32 *)((char *)mmesa->vertex_dma_buffer->address +
+ mmesa->vertex_dma_buffer->used);
+
+ mmesa->vertex_dma_buffer->used += bytes;
+ return head;
+}
+
+
+void mgaFireILoadLocked( mgaContextPtr mmesa,
+ GLuint offset, GLuint length )
+{
+ if (!mmesa->iload_buffer) {
+ fprintf(stderr, "mgaFireILoad: no buffer\n");
+ return;
+ }
+
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "mgaFireILoad idx %d ofs 0x%x length %d\n",
+ mmesa->iload_buffer->idx, (int)offset, (int)length );
+
+ mga_iload_dma_ioctl( mmesa, offset, length );
+}
+
+void mgaGetILoadBufferLocked( mgaContextPtr mmesa )
+{
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
+ fprintf(stderr, "mgaGetIloadBuffer (buffer now %p)\n",
+ mmesa->iload_buffer);
+
+ mmesa->iload_buffer = mga_get_buffer_ioctl( mmesa );
+}
+
+
+ void mgaDDFlush( GLcontext *ctx )
{
- XF86DRIClipRectPtr pbox = mmesa->pClipRects;
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+
+
+ FLUSH_BATCH( mmesa );
+
+ /* This may be called redundantly - dispatch_age may trail what
+ * has actually been sent and processed by the hardware.
+ */
+ if (GET_DISPATCH_AGE( mmesa ) < mmesa->sarea->last_enqueue) {
+ LOCK_HARDWARE( mmesa );
+ if (0) fprintf(stderr, "mgaDDFlush %d %d\n", GET_DISPATCH_AGE( mmesa ), mmesa->sarea->last_enqueue);
+ mgaUpdateLock( mmesa, DRM_LOCK_FLUSH );
+ UNLOCK_HARDWARE( mmesa );
+ }
+}
+
+
+
+void mgaFireEltsLocked( mgaContextPtr mmesa,
+ GLuint start,
+ GLuint end,
+ GLuint discard )
+{
+ drm_clip_rect_t *pbox = (drm_clip_rect_t *)mmesa->pClipRects;
int nbox = mmesa->numClipRects;
+ drmBufPtr buffer = mmesa->elt_buf;
+ drm_mga_indices_t elts;
int i;
- if (mmesa->dirty)
+
+ if (0) fprintf(stderr, "FireElts %d %d\n", start/4, end/4);
+
+ if (!buffer)
+ return;
+
+ if (mmesa->dirty_cliprects & mmesa->draw_buffer)
+ mgaUpdateRects( mmesa, mmesa->draw_buffer );
+
+ if (mmesa->dirty & ~MGA_UPLOAD_CLIPRECTS)
mgaEmitHwStateLocked( mmesa );
- for (i = 0 ; i < nbox ; )
+ /* FIXME: Workaround bug in kernel module.
+ */
+ mmesa->sarea->dirty |= MGA_UPLOAD_CTX;
+
+ elts.idx = buffer->idx;
+ elts.start = start;
+ elts.end = end;
+ elts.discard = 0;
+
+ if (!nbox)
+ elts.end = start;
+
+ if (nbox >= MGA_NR_SAREA_CLIPRECTS)
+ mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
+
+ if (elts.end == start || !(mmesa->dirty & MGA_UPLOAD_CLIPRECTS))
{
- int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, nbox);
- XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)mmesa->sarea->boxes;
- mmesa->sarea->nbox = nr - i;
+ if (nbox == 1)
+ mmesa->sarea->nbox = 0;
+ else
+ mmesa->sarea->nbox = nbox;
+
+ if (0)
+ fprintf(stderr, "Firing elts -- case a nbox %d\n", nbox);
+
+ elts.discard = discard;
+ ioctl(mmesa->driFd, DRM_IOCTL_MGA_INDICES, &elts);
+ age_mmesa(mmesa, mmesa->sarea->last_enqueue);
+ }
+ else
+ {
+ for (i = 0 ; i < nbox ; )
+ {
+ int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, nbox);
+ drm_clip_rect_t *b = mmesa->sarea->boxes;
+
+ if (mmesa->scissor) {
+ mmesa->sarea->nbox = 0;
+
+ for ( ; i < nr ; i++) {
+ *b = pbox[i];
+ if (intersect_rect(b, b, &mmesa->scissor_rect)) {
+ mmesa->sarea->nbox++;
+ b++;
+ }
+ }
+
+ /* Culled?
+ */
+ if (!mmesa->sarea->nbox) {
+ if (nr < nbox) continue;
+ elts.end = start;
+ }
+ } else {
+ mmesa->sarea->nbox = nr - i;
+ for ( ; i < nr ; i++)
+ *b++ = pbox[i];
+ }
- for ( ; i < nr ; i++)
- *b++ = pbox[i];
-
- mga_vertex_dma_ioctl( mmesa );
+ /* Potentially finished with the buffer?
+ */
+ if (nr == nbox)
+ elts.discard = discard;
- break; /* fix dma multiple dispatch */
+ if (0)
+ fprintf(stderr, "Firing elts -- case b nbox %d\n", nbox);
+
+ mmesa->sarea->dirty |= MGA_UPLOAD_CLIPRECTS;
+ ioctl(mmesa->driFd, DRM_IOCTL_MGA_INDICES, &elts);
+ age_mmesa(mmesa, mmesa->sarea->last_enqueue);
+ }
}
- mga_get_buffer_ioctl( mmesa );
+ mmesa->dirty &= ~MGA_UPLOAD_CLIPRECTS;
+}
+
+void mgaGetEltBufLocked( mgaContextPtr mmesa )
+{
+ mmesa->elt_buf = mga_get_buffer_ioctl( mmesa );
}
+void mgaReleaseBufLocked( mgaContextPtr mmesa, drmBufPtr buffer )
+{
+ drm_mga_vertex_t vertex;
+
+ if (!buffer) return;
+
+ vertex.idx = buffer->idx;
+ vertex.used = 0;
+ vertex.discard = 1;
+ ioctl(mmesa->driFd, DRM_IOCTL_MGA_VERTEX, &vertex);
+}
void mgaDDInitIoctlFuncs( GLcontext *ctx )
{
ctx->Driver.Clear = mgaClear;
- ctx->Driver.Flush = 0;
+ ctx->Driver.Flush = mgaDDFlush;
ctx->Driver.Finish = mgaDDFinish;
}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h
index 22ca26e17..900e4a4f8 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h
+++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h
@@ -9,9 +9,37 @@ GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
void mgaSwapBuffers( mgaContextPtr mmesa );
+
+
+mgaUI32 *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords );
+
+
+void mgaGetILoadBufferLocked( mgaContextPtr mmesa );
+
+
+void mgaFireILoadLocked( mgaContextPtr mmesa,
+ GLuint offset, GLuint length );
+
+void mgaWaitAgeLocked( mgaContextPtr mmesa, int age );
+void mgaWaitAge( mgaContextPtr mmesa, int age );
+int mgaUpdateLock( mgaContextPtr mmesa, drmLockFlags flags );
+
void mgaFlushVertices( mgaContextPtr mmesa );
void mgaFlushVerticesLocked( mgaContextPtr mmesa );
+
+void mgaFireEltsLocked( mgaContextPtr mmesa,
+ GLuint start,
+ GLuint end,
+ GLuint discard );
+
+void mgaGetEltBufLocked( mgaContextPtr mmesa );
+void mgaReleaseBufLocked( mgaContextPtr mmesa, drmBufPtr buffer );
+
+void mgaFlushEltsLocked( mgaContextPtr mmesa );
+void mgaFlushElts( mgaContextPtr mmesa ) ;
+
+
/* upload texture
*/
@@ -19,5 +47,12 @@ void mgaDDFinish( GLcontext *ctx );
void mgaDDInitIoctlFuncs( GLcontext *ctx );
+#define FLUSH_BATCH(mmesa) do { \
+ if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) \
+ fprintf(stderr, "FLUSH_BATCH in %s\n", __FUNCTION__); \
+ if (mmesa->vertex_dma_buffer) mgaFlushVertices(mmesa); \
+ else if (mmesa->next_elt != mmesa->first_elt) mgaFlushElts(mmesa); \
+} while (0)
+
#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgalib.h b/xc/lib/GL/mesa/src/drv/mga/mgalib.h
index 3c4cdbbd8..e00525f7b 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgalib.h
+++ b/xc/lib/GL/mesa/src/drv/mga/mgalib.h
@@ -101,6 +101,21 @@ typedef void (*mga_interp_func)( GLfloat t,
#define MGA_BLEND_ENV_COLOR 0x1
#define MGA_BLEND_MULTITEX 0x2
+struct mga_elt_tab {
+ void (*emit_unclipped_verts)( struct vertex_buffer *VB );
+
+ void (*build_tri_verts)( mgaContextPtr mmesa,
+ struct vertex_buffer *VB,
+ GLfloat *O, GLuint *elt );
+
+ void (*interp)( GLfloat t, GLfloat *O,
+ const GLfloat *I, const GLfloat *J );
+
+ void (*project_and_emit_verts)( mgaContextPtr mmesa,
+ const GLfloat *verts,
+ GLuint *elts,
+ int nr );
+};
struct mga_context_t {
@@ -177,7 +192,7 @@ struct mga_context_t {
*/
int dirty_cliprects; /* which sets of cliprects are uptodate? */
int draw_buffer; /* which buffer are we rendering to */
- int drawOffset; /* draw buffer address in space */
+ unsigned int drawOffset; /* draw buffer address in space */
int read_buffer;
int readOffset;
int drawX, drawY; /* origin of drawable in draw buffer */
@@ -192,8 +207,8 @@ struct mga_context_t {
/* Texture aging and DMA based aging.
*/
unsigned int texAge[MGA_NR_TEX_HEAPS];/* texture LRU age */
- int dirtyAge; /* buffer age for synchronization */
- int lastSwap; /* throttling runaway apps */
+ unsigned int dirtyAge; /* buffer age for synchronization */
+ unsigned int lastSwap; /* throttling runaway apps */
@@ -208,6 +223,17 @@ struct mga_context_t {
__DRIscreenPrivate *driScreen;
mgaScreenPrivate *mgaScreen;
drm_mga_sarea_t *sarea;
+
+
+ /* New setupdma path
+ */
+ drmBufPtr elt_buf, retained_buf;
+ GLuint *first_elt, *next_elt;
+ GLfloat *next_vert;
+ GLuint next_vert_phys;
+ GLuint first_vert_phys;
+ struct mga_elt_tab *elt_tab;
+ GLfloat device_matrix[16];
};
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgapipeline.h b/xc/lib/GL/mesa/src/drv/mga/mgapipeline.h
index d42abddfe..dc0179227 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgapipeline.h
+++ b/xc/lib/GL/mesa/src/drv/mga/mgapipeline.h
@@ -12,4 +12,7 @@ extern GLboolean mgaDDBuildPrecalcPipeline( GLcontext *ctx );
extern void mgaDDFastPath( struct vertex_buffer *VB );
extern void mgaDDFastPathInit( void );
+extern void mgaDDEltPath( struct vertex_buffer *VB );
+extern void mgaDDEltPathInit( void );
+
#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgarender.c b/xc/lib/GL/mesa/src/drv/mga/mgarender.c
deleted file mode 100644
index 6f406db2d..000000000
--- a/xc/lib/GL/mesa/src/drv/mga/mgarender.c
+++ /dev/null
@@ -1,334 +0,0 @@
-#include <stdio.h>
-#include "mgadd.h"
-#include "mgavb.h"
-#include "mgadma.h"
-#include "mgalib.h"
-#include "mgatris.h"
-#include "mgastate.h"
-#include "xsmesaP.h"
-#include "enums.h"
-
-#define POINT(x) mga_draw_point(&gWin[x], psize)
-#define LINE(x,y) mga_draw_line(&gWin[x], &gWin[y], lwidth)
-#define TRI(x,y,z) mga_draw_triangle(&gWin[x], &gWin[y], &gWin[z])
-
-
-/* Direct, and no clipping required. I haven't written the clip funcs
- * yet, so this is only useful for the fast path, which does its own
- * clipping.
- */
-#define RENDER_POINTS( start, count ) \
-do { \
- GLuint e; \
- for(e=start;e<=count;e++) \
- POINT(elt[e]); \
-} while (0)
-
-#define RENDER_LINE( i1, i ) \
-do { \
- GLuint e1 = elt[i1], e = elt[i]; \
- LINE( e1, e ); \
-} while (0)
-
-
-#define RENDER_TRI( i2, i1, i, pv, parity) \
-do { \
-{ GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
- if (parity) {GLuint tmp = e2; e2 = e1; e1 = tmp;} \
- TRI(e2, e1, e); \
-}} while (0)
-
-
-#define RENDER_QUAD( i3, i2, i1, i, pv) \
-do { \
- GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
- TRI(e3, e2, e); \
- TRI(e2, e1, e); \
-} while (0)
-
-#define LOCAL_VARS \
- mgaVertexPtr gWin = MGA_DRIVER_DATA(VB)->verts; \
- const GLuint *elt = VB->EltPtr->data; \
- const GLfloat lwidth = VB->ctx->Line.Width; \
- const GLfloat psize = VB->ctx->Point.Size; \
- GLcontext *ctx = VB->ctx; \
- (void) lwidth; (void)psize; (void)ctx; (void) gWin;
-
-
-#define TAG(x) x##_mga_smooth_indirect
-#include "render_tmp.h"
-
-
-
-
-#define RENDER_POINTS( start, count ) \
-do { \
- GLuint e; \
- for(e=start;e<=count;e++) \
- POINT(e); \
-} while (0)
-
-#define RENDER_LINE( i1, i ) \
-do { \
- LINE( i1, i ); \
-} while (0)
-
-
-#define RENDER_TRI( i2, i1, i, pv, parity) \
-do { \
- GLuint e2 = i2, e1 = i1; \
- if (parity) {GLuint tmp = e2; e2 = e1; e1 = tmp;} \
- TRI(e2, e1, i); \
-} while (0)
-
-
-#define RENDER_QUAD( i3, i2, i1, i, pv) \
-do { \
- TRI(i3, i2, i); \
- TRI(i2, i1, i); \
-} while (0)
-
-#define LOCAL_VARS \
- mgaVertexPtr gWin = MGA_DRIVER_DATA(VB)->verts; \
- const GLfloat lwidth = VB->ctx->Line.Width; \
- const GLfloat psize = VB->ctx->Point.Size; \
- GLcontext *ctx = VB->ctx; \
- (void) lwidth; (void)psize; (void)ctx; (void) gWin;
-
-#define TAG(x) x##_mga_smooth_direct
-#include "render_tmp.h"
-
-
-
-
-
-/* Vertex array rendering via. the SetupDma function - no clipping required.
- */
-#define RENDER_POINTS( start, count ) \
-do { \
- FatalError("Dead code in mgarender.c\n"); \
-} while (0)
-
-#define RENDER_LINE( i1, i ) \
-do { \
- FatalError("Dead code in mgarender.c\n"); \
-} while (0)
-
-
-#define RENDER_TRI( i2, i1, i, pv, parity) \
-do { \
- GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
- if (/*parity*/0) {GLuint tmp = e2; e2 = e1; e1 = tmp;} \
- TRI(e2, e1, e); \
-} while (0)
-
-#define RENDER_QUAD( i3, i2, i1, i, pv) \
-do { \
- GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
- TRI(e3, e2, e); \
- TRI(e2, e1, e); \
-} while (0)
-
-#define LOCAL_VARS \
- mgaVertexBufferPtr mgaVB = MGA_DRIVER_DATA(VB); \
- mgaUI32 phys = mgaVB->vert_phys_start; \
- const GLuint *elt = VB->EltPtr->data; \
- (void) phys; (void) elt;
-
-#define PRESERVE_VB_DEFS
-#undef TRI
-#define VERT_ADDR_10( phys, elt ) ( phys + elt * 48 )
-#define TRI( ee0, ee1, ee2 ) \
-{ \
- mgaVB->elt_buf[0] = VERT_ADDR_10(phys, ee0); \
- mgaVB->elt_buf[1] = VERT_ADDR_10(phys, ee1); \
- mgaVB->elt_buf[2] = VERT_ADDR_10(phys, ee2); \
- mgaVB->elt_buf += 3; \
-}
-#define TAG(x) x##_mga_elt_10
-#include "render_tmp.h"
-
-
-#define TAG(x) x##_mga_elt_8
-#undef TRI
-#define VERT_ADDR_8( phys, elt ) ( phys + elt * 32 )
-#define TRI( ee0, ee1, ee2 ) \
-{ \
- mgaVB->elt_buf[0] = VERT_ADDR_8(phys, ee0); \
- mgaVB->elt_buf[1] = VERT_ADDR_8(phys, ee1); \
- mgaVB->elt_buf[2] = VERT_ADDR_8(phys, ee2); \
- mgaVB->elt_buf += 3; \
-}
-#include "render_tmp.h"
-
-
-
-
-/* Currently only used on the fast path - need a set of render funcs
- * for clipped primitives.
- */
-void mgaDDRenderElementsDirect( struct vertex_buffer *VB )
-{
- mgaVertexBufferPtr mgaVB = MGA_DRIVER_DATA(VB);
- GLcontext *ctx = VB->ctx;
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- GLenum prim = ctx->CVA.elt_mode;
- GLuint nr = VB->EltPtr->count;
- render_func func = render_tab_mga_smooth_indirect[prim];
- GLuint p = 0;
- mgaUI32 *start = mgaVB->elt_buf;
-
- struct vertex_buffer *saved_vb = ctx->VB;
-
- if (mmesa->new_state)
- mgaDDUpdateHwState( ctx );
-
- /* Are we using Setup DMA?
- */
- if (start) {
- switch (MGA_CONTEXT(ctx)->vertsize) {
- case 10:
- func = render_tab_mga_elt_10[prim];
- break;
- case 8:
- func = render_tab_mga_elt_8[prim];
- break;
- default:
- }
- }
-
- ctx->VB = VB;
-
- do {
- func( VB, 0, nr, 0 );
- } while (ctx->Driver.MultipassFunc &&
- ctx->Driver.MultipassFunc( VB, ++p ));
-
- ctx->VB = saved_vb;
-
-
- if (start && nr) {
- if (0)
- fprintf(stderr, "%d/%d elts\n", nr, mgaVB->elt_buf-start);
- mgaSetupDma( start, mgaVB->elt_buf - start );
- mgaVB->elt_buf = mgaVB->vert_buf = 0;
- }
-}
-
-
-void mgaDDRenderElementsImmediate( struct vertex_buffer *VB )
-{
- GLcontext *ctx = VB->ctx;
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- GLuint nr = VB->EltPtr->count;
- render_func *tab = render_tab_mga_smooth_indirect;
- GLuint parity = VB->Parity;
- GLuint p = 0;
- GLuint i, next;
-
- if (mmesa->new_state)
- mgaDDUpdateHwState( ctx );
-
- do {
- for ( i= VB->CopyStart ; i < nr ; parity = 0, i = next )
- {
- GLenum prim = VB->Primitive[i];
- next = VB->NextPrimitive[i];
- tab[prim]( VB, i, next, parity );
- }
- } while (ctx->Driver.MultipassFunc &&
- ctx->Driver.MultipassFunc( VB, ++p ));
-}
-
-
-void mgaDDRenderDirect( struct vertex_buffer *VB )
-{
- GLcontext *ctx = VB->ctx;
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- GLuint nr = VB->Count;
- render_func *tab = render_tab_mga_smooth_direct;
- GLuint parity = VB->Parity;
- GLuint p = 0;
- GLuint i, next;
-
- if (mmesa->new_state)
- mgaDDUpdateHwState( ctx );
-
- do {
- for ( i= VB->CopyStart ; i < nr ; parity = 0, i = next )
- {
- GLenum prim = VB->Primitive[i];
- next = VB->NextPrimitive[i];
- tab[prim]( VB, i, next, parity );
- }
- } while (ctx->Driver.MultipassFunc &&
- ctx->Driver.MultipassFunc( VB, ++p ));
-}
-
-
-static void optimized_render_vb_triangle_mga_smooth_indirect(struct vertex_buffer *VB,
- GLuint start,
- GLuint count,
- GLuint parity)
-{
- mgaVertexPtr gWin = MGA_DRIVER_DATA(VB)->verts;
- const GLuint *elt = VB->EltPtr->data;
- GLcontext *ctx = VB->ctx;
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
-
- mgaUI32 vertsize = mmesa->vertsize;
-
- /* We know how many dwords we need so we can allocate all of it
- * in one call */
- mgaUI32 *wv = mgaAllocSecondaryBuffer( count * vertsize );
-
- int vertex;
-
- (void)ctx; (void) gWin; (void) parity;
-
-
- for(vertex=start+2;vertex<count;vertex+=3){
- GLuint e2=elt[vertex-2],e1=elt[vertex-1],e=elt[vertex];
- mgaUI32 *src;
-
- int j;
-
- if(parity){
- GLuint tmp=e2;
- e2=e1;
- e1=tmp;
- }
-
- src=&gWin[e2].ui[0];
-
- for(j=vertsize;j;j--){
- *wv++=*src++;
- }
-
- src=&gWin[e1].ui[0];
- for(j=vertsize;j;j--){
- *wv++=*src++;
- }
-
- src=&gWin[e].ui[0];
- for(j=vertsize;j;j--){
- *wv++=*src++;
- }
- }
-
-}
-
-
-void mgaDDRenderInit()
-{
-
- render_init_mga_smooth_indirect();
- render_init_mga_smooth_direct();
- render_init_mga_elt_10();
- render_init_mga_elt_8();
-
- render_tab_mga_smooth_indirect[GL_TRIANGLES] =
- optimized_render_vb_triangle_mga_smooth_indirect;
-}
-
-
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgarender.h b/xc/lib/GL/mesa/src/drv/mga/mgarender.h
deleted file mode 100644
index c772ac459..000000000
--- a/xc/lib/GL/mesa/src/drv/mga/mgarender.h
+++ /dev/null
@@ -1,10 +0,0 @@
-
-#ifndef _MGA_RENDER_H
-#define _MGA_RENDER_H
-
-extern void mgaDDRenderElementsDirect( struct vertex_buffer *VB );
-extern void mgaDDRenderElementsImmediate( struct vertex_buffer *VB );
-extern void mgaDDRenderDirect( struct vertex_buffer *VB );
-extern void mgaDDRenderInit();
-
-#endif
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgastate.c b/xc/lib/GL/mesa/src/drv/mga/mgastate.c
index ff9063e0b..7a3b82930 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgastate.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgastate.c
@@ -16,7 +16,7 @@
#include "mgavb.h"
#include "mgatris.h"
#include "mgaregs.h"
-#include "mga_drm_public.h"
+#include "mgabuffers.h"
static void mgaUpdateZMode(const GLcontext *ctx)
{
@@ -60,17 +60,20 @@ static void mgaUpdateZMode(const GLcontext *ctx)
static void mgaDDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref)
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
}
static void mgaDDBlendEquation(GLcontext *ctx, GLenum mode)
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
}
static void mgaDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
}
@@ -78,6 +81,7 @@ static void mgaDDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB,
GLenum dfactorRGB, GLenum sfactorA,
GLenum dfactorA )
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
}
@@ -87,6 +91,7 @@ static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname,
const GLfloat *param)
{
if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
}
}
@@ -95,6 +100,7 @@ static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname,
static void mgaDDShadeModel(GLcontext *ctx, GLenum mode)
{
if (1) {
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
mgaMsg(8, "mgaDDShadeModel: %x\n", mode);
}
@@ -103,11 +109,13 @@ static void mgaDDShadeModel(GLcontext *ctx, GLenum mode)
static void mgaDDDepthFunc(GLcontext *ctx, GLenum func)
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH;
}
static void mgaDDDepthMask(GLcontext *ctx, GLboolean flag)
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH;
}
@@ -134,6 +142,7 @@ static void mgaUpdateFogAttrib( GLcontext *ctx )
static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_FOG;
}
@@ -148,10 +157,11 @@ static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
static void mgaUpdateAlphaMode(GLcontext *ctx)
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
int a = 0;
/* determine source of alpha for blending and testing */
- if ( !ctx->Texture.Enabled || (mmesa->Fallback & MGA_FALLBACK_TEXTURE))
+ if ( !ctx->Texture.Enabled )
a |= AC_alphasel_diffused;
else {
switch (ctx->Texture.Unit[0].EnvMode) {
@@ -168,7 +178,7 @@ static void mgaUpdateAlphaMode(GLcontext *ctx)
}
- /* alpha test control - disabled by default.
+ /* alpha test control.
*/
if (ctx->Color.AlphaEnabled) {
GLubyte ref = ctx->Color.AlphaRef;
@@ -219,13 +229,13 @@ static void mgaUpdateAlphaMode(GLcontext *ctx)
case GL_ONE_MINUS_SRC_ALPHA:
a |= AC_src_om_src_alpha; break;
case GL_DST_ALPHA:
- if (0) /*(mgaScreen->Attrib & MGA_PF_HASALPHA)*/
+ if (mgaScreen->Attrib & MGA_PF_HASALPHA)
a |= AC_src_dst_alpha;
else
a |= AC_src_one;
break;
case GL_ONE_MINUS_DST_ALPHA:
- if (0) /*(mgaScreen->Attrib & MGA_PF_HASALPHA)*/
+ if (mgaScreen->Attrib & MGA_PF_HASALPHA)
a |= AC_src_om_dst_alpha;
else
a |= AC_src_zero;
@@ -250,13 +260,13 @@ static void mgaUpdateAlphaMode(GLcontext *ctx)
case GL_ONE_MINUS_SRC_COLOR:
a |= AC_dst_om_src_color; break;
case GL_DST_ALPHA:
- if (0) /*(mgaDB->Attrib & MGA_PF_HASALPHA)*/
+ if (mgaScreen->Attrib & MGA_PF_HASALPHA)
a |= AC_dst_dst_alpha;
else
a |= AC_dst_one;
break;
case GL_ONE_MINUS_DST_ALPHA:
- if (0) /*(mgaScreen->Attrib & MGA_PF_HASALPHA)*/
+ if (mgaScreen->Attrib & MGA_PF_HASALPHA)
a |= AC_dst_om_dst_alpha;
else
a |= AC_dst_zero;
@@ -282,50 +292,44 @@ static void mgaUpdateAlphaMode(GLcontext *ctx)
* Hardware clipping
*/
-static void mgaUpdateClipping(const GLcontext *ctx)
+void mgaUpdateClipping(const GLcontext *ctx)
{
-#if 0
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
- int x1,x2,y1,y2;
-
- if ( ctx->Scissor.Enabled) {
- x1 = ctx->Scissor.X;
- x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
- y1 = dPriv->Height - ctx->Scissor.Y - ctx->Scissor.Height;
- y2 = dPriv->Height - ctx->Scissor.Y - 1;
- } else {
- x1 = 0;
- y1 = 0;
- x2 = mgaDB->Width-1;
- y2 = mgaDB->Height-1;
- }
-
- if (x1 < 0) x1 = 0;
- if (y1 < 0) y1 = 0;
- if (x2 >= mgaDB->Width) x2 = mgaDB->Width-1;
- if (y2 >= mgaDB->Height) y2 = mgaDB->Height-1;
-
- if (x1 > x2 || y1 > y2) {
- x1 = 0; x2 = 0;
- y2 = 0; y1 = 1;
- }
-
-
- mmesa->Setup[MGA_CTXREG_CXBNDRY] = (MGA_FIELD(CXB_cxright,x2) |
- MGA_FIELD(CXB_cxleft,x1));
- mmesa->Setup[MGA_CTXREG_YTOP] = y1*mgaDB->Pitch;
- mmesa->Setup[MGA_CTXREG_YBOT] = y2*mgaDB->Pitch;
-
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
- mmesa->dirty |= MGA_UPLOAD_CTX;
-#endif
+ if (mmesa->driDrawable)
+ {
+ int x1 = mmesa->driDrawable->x + ctx->Scissor.X;
+ int y1 = mmesa->driDrawable->y + mmesa->driDrawable->h - (ctx->Scissor.Y+
+ ctx->Scissor.Height);
+ int x2 = mmesa->driDrawable->x + ctx->Scissor.X+ctx->Scissor.Width;
+ int y2 = mmesa->driDrawable->y + mmesa->driDrawable->h - ctx->Scissor.Y;
+
+ if (x1 < 0) x1 = 0;
+ if (y1 < 0) y1 = 0;
+ if (x2 < 0) x2 = 0;
+ if (y2 < 0) y2 = 0;
+
+ mmesa->scissor_rect.x1 = x1;
+ mmesa->scissor_rect.y1 = y1;
+ mmesa->scissor_rect.x2 = x2;
+ mmesa->scissor_rect.y2 = y2;
+
+ if (MGA_DEBUG&DEBUG_VERBOSE_2D)
+ fprintf(stderr, "SET SCISSOR %d,%d-%d,%d\n",
+ mmesa->scissor_rect.x1,
+ mmesa->scissor_rect.y1,
+ mmesa->scissor_rect.x2,
+ mmesa->scissor_rect.y2);
+
+ mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
+ }
}
static void mgaDDScissor( GLcontext *ctx, GLint x, GLint y,
GLsizei w, GLsizei h )
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CLIP;
}
@@ -339,35 +343,6 @@ static void mgaDDDither(GLcontext *ctx, GLboolean enable)
}
-static GLboolean mgaDDSetBuffer(GLcontext *ctx, GLenum mode )
-{
- mgaContextPtr mmesa = MGA_CONTEXT(ctx);
-
- mmesa->Fallback &= ~MGA_FALLBACK_BUFFER;
-
- if (mode == GL_FRONT_LEFT)
- {
- mmesa->drawOffset = mmesa->mgaScreen->fbOffset;
- mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->fbOffset;
- mmesa->dirty |= MGA_UPLOAD_CTX;
- mgaXMesaSetFrontClipRects( mmesa );
- return GL_TRUE;
- }
- else if (mode == GL_BACK_LEFT)
- {
- mmesa->drawOffset = mmesa->mgaScreen->backOffset;
- mmesa->Setup[MGA_CTXREG_DSTORG] = mmesa->mgaScreen->backOffset;
- mmesa->dirty |= MGA_UPLOAD_CTX;
- mgaXMesaSetBackClipRects( mmesa );
- return GL_TRUE;
- }
- else
- {
- mmesa->Fallback |= MGA_FALLBACK_BUFFER;
- return GL_FALSE;
- }
-}
-
static void mgaDDSetColor(GLcontext *ctx,
@@ -376,7 +351,7 @@ static void mgaDDSetColor(GLcontext *ctx,
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
- mmesa->MonoColor = mgaPackColor( mmesa->mgaScreen->fbFormat,
+ mmesa->MonoColor = mgaPackColor( mmesa->mgaScreen->Attrib,
r, g, b, a );
}
@@ -387,7 +362,7 @@ static void mgaDDClearColor(GLcontext *ctx,
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
- mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->fbFormat,
+ mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->Attrib,
r, g, b, a );
}
@@ -426,6 +401,7 @@ static void mgaUpdateCull( GLcontext *ctx )
static void mgaDDCullFaceFrontFace(GLcontext *ctx, GLenum mode)
{
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CULL;
}
@@ -461,6 +437,7 @@ static GLboolean mgaDDColorMask(GLcontext *ctx,
}
if (mmesa->Setup[MGA_CTXREG_PLNWT] != mask) {
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
mmesa->Setup[MGA_CTXREG_PLNWT] = mask;
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_MASK;
mmesa->dirty |= MGA_UPLOAD_CTX;
@@ -470,6 +447,83 @@ static GLboolean mgaDDColorMask(GLcontext *ctx,
}
/* =============================================================
+ * Polygon stipple
+ *
+ * The mga supports a subset of possible 4x4 stipples natively, GL
+ * wants 32x32. Fortunately stipple is usually a repeating pattern.
+ */
+static int mgaStipples[16] = {
+ 0xffff,
+ 0xa5a5,
+ 0x5a5a,
+ 0xa0a0,
+ 0x5050,
+ 0x0a0a,
+ 0x0505,
+ 0x8020,
+ 0x0401,
+ 0x1040,
+ 0x0208,
+ 0x0802,
+ 0x4010,
+ 0x0104,
+ 0x2080,
+ 0x0000
+};
+
+static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+ const GLubyte *m = mask;
+ GLubyte p[4];
+ int i,j,k;
+ int active = (ctx->Polygon.StippleFlag && ctx->PB->primitive == GL_POLYGON);
+ GLuint stipple;
+
+ FLUSH_BATCH(mmesa);
+ ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE;
+
+ if (active) {
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+ mmesa->Setup[MGA_CTXREG_DWGCTL] &= ~(0xf<<20);
+ }
+
+ p[0] = mask[0] & 0xf; p[0] |= p[0] << 4;
+ p[1] = mask[4] & 0xf; p[1] |= p[1] << 4;
+ p[2] = mask[8] & 0xf; p[2] |= p[2] << 4;
+ p[3] = mask[12] & 0xf; p[3] |= p[3] << 4;
+
+ for (k = 0 ; k < 8 ; k++)
+ for (j = 0 ; j < 4; j++)
+ for (i = 0 ; i < 4 ; i++)
+ if (*m++ != p[j]) {
+ ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE;
+ return;
+ }
+
+ stipple = ( ((p[0] & 0xf) << 0) |
+ ((p[1] & 0xf) << 4) |
+ ((p[2] & 0xf) << 8) |
+ ((p[3] & 0xf) << 12) );
+
+ for (i = 0 ; i < 16 ; i++)
+ if (mgaStipples[i] == stipple) {
+ mmesa->poly_stipple = i<<20;
+ break;
+ }
+
+ if (i == 16) {
+ ctx->Driver.TriangleCaps &= ~DD_TRI_STIPPLE;
+ return;
+ }
+
+ if (active) {
+ mmesa->Setup[MGA_CTXREG_DWGCTL] &= ~(0xf<<20);
+ mmesa->Setup[MGA_CTXREG_DWGCTL] |= mmesa->poly_stipple;
+ }
+}
+
+/* =============================================================
*/
@@ -477,15 +531,16 @@ static GLboolean mgaDDColorMask(GLcontext *ctx,
static void mgaDDPrintDirty( const char *msg, GLuint state )
{
- fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s\n",
+ fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n",
msg,
(unsigned int) state,
- (state & MGA_REQUIRE_QUIESCENT) ? "req-quiescent, " : "",
+ (state & MGA_WAIT_AGE) ? "wait-age, " : "",
(state & MGA_UPLOAD_TEX0IMAGE) ? "upload-tex0-img, " : "",
(state & MGA_UPLOAD_TEX1IMAGE) ? "upload-tex1-img, " : "",
(state & MGA_UPLOAD_CTX) ? "upload-ctx, " : "",
(state & MGA_UPLOAD_TEX0) ? "upload-tex0, " : "",
- (state & MGA_UPLOAD_TEX1) ? "upload-tex1, " : ""
+ (state & MGA_UPLOAD_TEX1) ? "upload-tex1, " : "",
+ (state & MGA_UPLOAD_PIPE) ? "upload-pipe, " : ""
);
}
@@ -494,7 +549,7 @@ static void mgaDDPrintDirty( const char *msg, GLuint state )
*/
void mgaEmitHwStateLocked( mgaContextPtr mmesa )
{
- if (MGA_DEBUG & MGA_DEBUG_VERBOSE_MSG)
+ if (MGA_DEBUG & DEBUG_VERBOSE_MSG)
mgaDDPrintDirty( "mgaEmitHwStateLocked", mmesa->dirty );
if ((mmesa->dirty & MGA_UPLOAD_TEX0IMAGE) && mmesa->CurrentTexObj[0])
@@ -503,27 +558,34 @@ void mgaEmitHwStateLocked( mgaContextPtr mmesa )
if ((mmesa->dirty & MGA_UPLOAD_TEX1IMAGE) && mmesa->CurrentTexObj[1])
mgaUploadTexImages(mmesa, mmesa->CurrentTexObj[1]);
- if (mmesa->dirty & MGA_UPLOAD_CTX) {
+ if (mmesa->dirty & MGA_UPLOAD_CTX)
memcpy( mmesa->sarea->ContextState,
mmesa->Setup,
sizeof(mmesa->Setup));
- if (mmesa->CurrentTexObj[0])
+ if ((mmesa->dirty & MGA_UPLOAD_TEX0) && mmesa->CurrentTexObj[0])
memcpy(mmesa->sarea->TexState[0],
mmesa->CurrentTexObj[0]->Setup,
sizeof(mmesa->sarea->TexState[0]));
- if (mmesa->CurrentTexObj[1])
+ if ((mmesa->dirty & MGA_UPLOAD_TEX1) && mmesa->CurrentTexObj[1])
memcpy(mmesa->sarea->TexState[1],
mmesa->CurrentTexObj[1]->Setup,
sizeof(mmesa->sarea->TexState[1]));
- }
- if (mmesa->dirty & MGA_UPLOAD_PIPE)
- mmesa->sarea->WarpPipe = mmesa->setupindex & MGA_WARP_T2GZSAF;
-
+ mmesa->sarea->WarpPipe = ((mmesa->setupindex & MGA_WARP_T2GZSAF) |
+ MGA_ALPHA_BIT | MGA_SPEC_BIT | MGA_FOG_BIT);
+
+
mmesa->sarea->dirty |= mmesa->dirty;
- mmesa->dirty = 0;
+
+#if 0
+ mgaPrintSetupFlags("warp pipe", mmesa->sarea->WarpPipe);
+ fprintf(stderr, "in mgaEmitHwStateLocked: dirty now %x\n",
+ mmesa->sarea->dirty);
+#endif
+
+ mmesa->dirty &= (MGA_UPLOAD_CLIPRECTS|MGA_WAIT_AGE);
}
@@ -533,29 +595,50 @@ void mgaEmitHwStateLocked( mgaContextPtr mmesa )
static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+
switch(cap) {
case GL_ALPHA_TEST:
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
+ FLUSH_BATCH( mmesa );
+ mmesa->new_state |= MGA_NEW_ALPHA;
break;
case GL_BLEND:
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
+ FLUSH_BATCH( mmesa );
+ mmesa->new_state |= MGA_NEW_ALPHA;
break;
case GL_DEPTH_TEST:
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH;
+ FLUSH_BATCH( mmesa );
+ mmesa->new_state |= MGA_NEW_DEPTH;
break;
case GL_SCISSOR_TEST:
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CLIP;
+ FLUSH_BATCH( mmesa );
+ mmesa->scissor = state;
+ mmesa->new_state |= MGA_NEW_CLIP;
break;
case GL_FOG:
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_FOG;
+ FLUSH_BATCH( mmesa );
+ mmesa->new_state |= MGA_NEW_FOG;
break;
case GL_CULL_FACE:
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CULL;
+ FLUSH_BATCH( mmesa );
+ mmesa->new_state |= MGA_NEW_CULL;
break;
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
case GL_TEXTURE_3D:
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
+ FLUSH_BATCH( mmesa );
+ mmesa->new_state |= MGA_NEW_TEXTURE;
+ break;
+ case GL_POLYGON_STIPPLE:
+ if ((ctx->Driver.TriangleCaps & DD_TRI_STIPPLE) &&
+ ctx->PB->primitive == GL_POLYGON)
+ {
+ FLUSH_BATCH(mmesa);
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+ mmesa->Setup[MGA_CTXREG_DWGCTL] &= ~(0xf<<20);
+ if (state)
+ mmesa->Setup[MGA_CTXREG_DWGCTL] |= mmesa->poly_stipple;
+ }
break;
default:
;
@@ -581,6 +664,7 @@ static void mgaWarpUpdateState( GLcontext *ctx )
{
mmesa->warp_pipe = index;
mmesa->new_state |= MGA_NEW_WARP;
+ mmesa->dirty |= MGA_UPLOAD_PIPE;
}
}
@@ -611,21 +695,15 @@ void mgaDDUpdateHwState( GLcontext *ctx )
if (new_state)
{
- mmesa->new_state = 0;
+ FLUSH_BATCH( mmesa );
- /* Emit any vertices for the current state. This will also
- * push the current state into the sarea.
- */
-/* mgaFlushVertices( mmesa ); */
+ mmesa->new_state = 0;
if (MESA_VERBOSE&VERBOSE_DRIVER)
mgaDDPrintState("UpdateHwState", new_state);
if (new_state & MGA_NEW_DEPTH)
- {
mgaUpdateZMode(ctx);
- mgaDDInitDepthFuncs(ctx);
- }
if (new_state & MGA_NEW_ALPHA)
mgaUpdateAlphaMode(ctx);
@@ -641,8 +719,6 @@ void mgaDDUpdateHwState( GLcontext *ctx )
if (new_state & (MGA_NEW_WARP|MGA_NEW_TEXTURE))
mgaUpdateTextureState(ctx);
-
- mmesa->new_state = 0; /* tex uploads scribble newstate */
}
}
@@ -654,8 +730,17 @@ void mgaDDUpdateHwState( GLcontext *ctx )
void mgaDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim )
{
- mgaFlushVertices( MGA_CONTEXT(ctx) );
- mgaUpdateCull(ctx);
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+ FLUSH_BATCH( mmesa );
+ mgaUpdateCull(ctx);
+
+ if (ctx->Polygon.StippleFlag && (ctx->Driver.TriangleCaps & DD_TRI_STIPPLE))
+ {
+ mmesa->Setup[MGA_CTXREG_DWGCTL] &= ~(0xf<<20);
+ if (ctx->PB->primitive == GL_POLYGON)
+ mmesa->Setup[MGA_CTXREG_DWGCTL] |= mmesa->poly_stipple;
+ }
}
@@ -677,10 +762,16 @@ void mgaDDUpdateState( GLcontext *ctx )
/* Have to do this here to detect texture fallbacks in time:
*/
- if (MGA_CONTEXT(ctx)->new_state & MGA_NEW_TEXTURE)
+ if (mmesa->new_state & MGA_NEW_TEXTURE)
mgaDDUpdateHwState( ctx );
- if (!mmesa->Fallback || mgaglx.noFallback) {
+ if (0) fprintf(stderr, "fallback %x indirect %x\n", mmesa->Fallback,
+ mmesa->IndirectTriangles);
+
+ if (!mmesa->Fallback) {
+ ctx->IndirectTriangles &= ~DD_SW_RASTERIZE;
+ ctx->IndirectTriangles |= mmesa->IndirectTriangles;
+
ctx->Driver.PointsFunc=mmesa->PointsFunc;
ctx->Driver.LineFunc=mmesa->LineFunc;
ctx->Driver.TriangleFunc=mmesa->TriangleFunc;
@@ -689,6 +780,60 @@ void mgaDDUpdateState( GLcontext *ctx )
}
+
+void mgaInitState( mgaContextPtr mmesa )
+{
+ mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
+ GLcontext *ctx = mmesa->glCtx;
+
+ if (ctx->Color.DriverDrawBuffer == GL_BACK_LEFT) {
+ mmesa->draw_buffer = MGA_BACK;
+ mmesa->read_buffer = MGA_BACK;
+ mmesa->drawOffset = mmesa->mgaScreen->backOffset;
+ mmesa->readOffset = mmesa->mgaScreen->backOffset;
+ mmesa->Setup[MGA_CTXREG_DSTORG] = mgaScreen->backOffset;
+ } else {
+ mmesa->drawOffset = mmesa->mgaScreen->frontOffset;
+ mmesa->readOffset = mmesa->mgaScreen->frontOffset;
+ mmesa->draw_buffer = MGA_FRONT;
+ mmesa->read_buffer = MGA_FRONT;
+ mmesa->Setup[MGA_CTXREG_DSTORG] = mgaScreen->frontOffset;
+ }
+
+/* mmesa->Setup[MGA_CTXREG_MACCESS] = mgaScreen->mAccess; */
+/* mmesa->Setup[MGA_CTXREG_DWGCTL] = ( DC_clipdis_disable | */
+/* (0xC << DC_bop_SHIFT) | */
+/* DC_shftzero_enable | */
+/* DC_zmode_nozcmp | */
+/* DC_atype_zi ); */
+
+
+ mmesa->Setup[MGA_CTXREG_MACCESS] = 0x1;
+ mmesa->Setup[MGA_CTXREG_DWGCTL] = 0xc4074;
+
+
+ mmesa->Setup[MGA_CTXREG_PLNWT] = ~0;
+ mmesa->Setup[MGA_CTXREG_ALPHACTRL] = ( AC_src_one |
+ AC_dst_zero |
+ AC_amode_FCOL |
+ AC_astipple_disable |
+ AC_aten_disable |
+ AC_atmode_noacmp |
+ AC_alphasel_fromtex );
+
+ mmesa->Setup[MGA_CTXREG_FOGCOLOR] =
+ MGAPACKCOLOR888((GLubyte)(ctx->Fog.Color[0]*255.0F),
+ (GLubyte)(ctx->Fog.Color[1]*255.0F),
+ (GLubyte)(ctx->Fog.Color[2]*255.0F));
+
+ mmesa->Setup[MGA_CTXREG_WFLAG] = 0;
+ mmesa->Setup[MGA_CTXREG_TDUAL0] = 0;
+ mmesa->Setup[MGA_CTXREG_TDUAL1] = 0;
+ mmesa->Setup[MGA_CTXREG_FCOL] = 0;
+ mmesa->new_state = ~0;
+}
+
+
void mgaDDInitStateFuncs( GLcontext *ctx )
{
ctx->Driver.UpdateState = mgaDDUpdateState;
@@ -710,11 +855,14 @@ void mgaDDInitStateFuncs( GLcontext *ctx )
ctx->Driver.RenderStart = mgaDDUpdateHwState;
ctx->Driver.RenderFinish = 0;
- ctx->Driver.SetBuffer = mgaDDSetBuffer;
+ ctx->Driver.SetDrawBuffer = mgaDDSetDrawBuffer;
+ ctx->Driver.SetReadBuffer = mgaDDSetReadBuffer;
ctx->Driver.Color = mgaDDSetColor;
ctx->Driver.ClearColor = mgaDDClearColor;
ctx->Driver.Dither = mgaDDDither;
+ ctx->Driver.PolygonStipple = mgaDDPolygonStipple;
+
ctx->Driver.Index = 0;
ctx->Driver.ClearIndex = 0;
ctx->Driver.IndexMask = 0;
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.c b/xc/lib/GL/mesa/src/drv/mga/mgatex.c
index be7ad6018..eafccbaa2 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgatex.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.c
@@ -47,22 +47,25 @@
* to it.
*/
static void mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t ) {
- int i;
if ( !t ) return;
/* free the texture memory */
- mmFreeMem( t->MemBlock );
+ if (t->MemBlock) {
+ mmFreeMem( t->MemBlock );
+ t->MemBlock = 0;
+
+ if (t->age > mmesa->dirtyAge)
+ mmesa->dirtyAge = t->age;
+ }
/* free mesa's link */
- t->tObj->DriverData = NULL;
+ if (t->tObj)
+ t->tObj->DriverData = NULL;
/* see if it was the driver's current object */
- for ( i = 0 ; i < 2 ; i++ ) {
- if ( mmesa->CurrentTexObj[i] == t ) {
- mmesa->CurrentTexObj[i] = NULL;
- }
- }
+ if (t->bound)
+ mmesa->CurrentTexObj[t->bound - 1] = 0;
remove_from_list(t);
free( t );
@@ -73,6 +76,9 @@ static void mgaSwapOutTexObj(mgaContextPtr mmesa, mgaTextureObjectPtr t)
if (t->MemBlock) {
mmFreeMem(t->MemBlock);
t->MemBlock = 0;
+
+ if (t->age > mmesa->dirtyAge)
+ mmesa->dirtyAge = t->age;
}
t->dirty_images = ~0;
@@ -80,22 +86,76 @@ static void mgaSwapOutTexObj(mgaContextPtr mmesa, mgaTextureObjectPtr t)
}
-void mgaResetGlobalLRU( mgaContextPtr mmesa )
+static void mgaPrintLocalLRU( mgaContextPtr mmesa, int heap )
+{
+ mgaTextureObjectPtr t;
+ int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]);
+
+ fprintf(stderr, "\nLocal LRU, heap %d:\n", heap);
+
+ foreach( t, &(mmesa->TexObjList[heap]) ) {
+ if (!t->tObj)
+ fprintf(stderr, "Placeholder %d at %x sz %x\n",
+ t->MemBlock->ofs / sz,
+ t->MemBlock->ofs,
+ t->MemBlock->size);
+ else
+ fprintf(stderr, "Texture (bound %d) at %x sz %x\n",
+ t->bound,
+ t->MemBlock->ofs,
+ t->MemBlock->size);
+
+ }
+
+ fprintf(stderr, "\n\n");
+}
+
+static void mgaPrintGlobalLRU( mgaContextPtr mmesa, int heap )
+{
+ int i, j;
+ drm_mga_tex_region_t *list = mmesa->sarea->texList[heap];
+
+ fprintf(stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list);
+
+ for (i = 0, j = MGA_NR_TEX_REGIONS ; i < MGA_NR_TEX_REGIONS ; i++) {
+ fprintf(stderr, "list[%d] age %d next %d prev %d\n",
+ j, list[j].age, list[j].next, list[j].prev);
+ j = list[j].next;
+ if (j == MGA_NR_TEX_REGIONS) break;
+ }
+
+ if (j != MGA_NR_TEX_REGIONS) {
+ fprintf(stderr, "Loop detected in global LRU\n\n\n");
+ for (i = 0 ; i < MGA_NR_TEX_REGIONS ; i++) {
+ fprintf(stderr, "list[%d] age %d next %d prev %d\n",
+ i, list[i].age, list[i].next, list[i].prev);
+ }
+ }
+
+ fprintf(stderr, "\n\n");
+}
+
+
+static void mgaResetGlobalLRU( mgaContextPtr mmesa, GLuint heap )
{
- mgaTexRegion *list = mmesa->sarea->texList;
- int sz = 1 << mmesa->mgaScreen->logTextureGranularity;
+ drm_mga_tex_region_t *list = mmesa->sarea->texList[heap];
+ int sz = 1 << mmesa->mgaScreen->logTextureGranularity[heap];
int i;
+ mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap];
+
+ if (0) fprintf(stderr, "mgaResetGlobalLRU %d\n", (int)heap);
+
/* (Re)initialize the global circular LRU list. The last element
* in the array (MGA_NR_TEX_REGIONS) is the sentinal. Keeping it
* at the end of the array allows it to be addressed rationally
* when looking up objects at a particular location in texture
* memory.
*/
- for (i = 0 ; (i+1) * sz < mmesa->mgaScreen->textureSize ; i++) {
+ for (i = 0 ; (i+1) * sz <= mmesa->mgaScreen->textureSize[heap] ; i++) {
list[i].prev = i-1;
list[i].next = i+1;
- list[i].age = 0;
+ list[i].age = mmesa->sarea->texAge[heap];
}
i--;
@@ -104,30 +164,41 @@ void mgaResetGlobalLRU( mgaContextPtr mmesa )
list[i].next = MGA_NR_TEX_REGIONS;
list[MGA_NR_TEX_REGIONS].prev = i;
list[MGA_NR_TEX_REGIONS].next = 0;
- mmesa->sarea->texAge = 0;
+
}
static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t )
{
int i;
- int logsz = mmesa->mgaScreen->logTextureGranularity;
+ int heap = t->heap;
+ int logsz = mmesa->mgaScreen->logTextureGranularity[heap];
int start = t->MemBlock->ofs >> logsz;
int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz;
- mgaTexRegion *list = mmesa->sarea->texList;
+ drm_mga_tex_region_t *list = mmesa->sarea->texList[heap];
- mmesa->texAge = ++mmesa->sarea->texAge;
+ mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap];
+
+ if (!t->MemBlock) {
+ fprintf(stderr, "no memblock\n\n");
+ return;
+ }
/* Update our local LRU
*/
- move_to_head( &(mmesa->TexObjList), t );
+ move_to_head( &(mmesa->TexObjList[heap]), t );
+
+
+ if (0)
+ fprintf(stderr, "mgaUpdateTexLRU heap %d list %p\n", heap, list);
+
/* Update the global LRU
*/
for (i = start ; i <= end ; i++) {
list[i].in_use = 1;
- list[i].age = mmesa->texAge;
+ list[i].age = mmesa->texAge[heap];
/* remove_from_list(i)
*/
@@ -141,8 +212,12 @@ static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t )
list[(unsigned)list[MGA_NR_TEX_REGIONS].next].prev = i;
list[MGA_NR_TEX_REGIONS].next = i;
}
-}
+ if (0) {
+ mgaPrintGlobalLRU(mmesa, t->heap);
+ mgaPrintLocalLRU(mmesa, t->heap);
+ }
+}
/* Called for every shared texture region which has increased in age
* since we last held the lock.
@@ -151,23 +226,29 @@ static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t )
* and pushes a placeholder texture onto the LRU list to represent
* the other client's textures.
*/
-void mgaTexturesGone( mgaContextPtr mmesa,
- GLuint offset,
- GLuint size,
- GLuint in_use )
+static void mgaTexturesGone( mgaContextPtr mmesa,
+ GLuint heap,
+ GLuint offset,
+ GLuint size,
+ GLuint in_use )
{
mgaTextureObjectPtr t, tmp;
-
- foreach_s ( t, tmp, &mmesa->TexObjList ) {
+
+
+
+ foreach_s ( t, tmp, &(mmesa->TexObjList[heap]) ) {
if (t->MemBlock->ofs >= offset + size ||
t->MemBlock->ofs + t->MemBlock->size <= offset)
continue;
+
+
+
/* It overlaps - kick it off. Need to hold onto the currently bound
* objects, however.
*/
- if (t == mmesa->CurrentTexObj[0] || t == mmesa->CurrentTexObj[1])
+ if (t->bound)
mgaSwapOutTexObj( mmesa, t );
else
mgaDestroyTexObj( mmesa, t );
@@ -178,12 +259,54 @@ void mgaTexturesGone( mgaContextPtr mmesa,
t = (mgaTextureObjectPtr) calloc(1,sizeof(*t));
if (!t) return;
- t->MemBlock = mmAllocMem( mmesa->texHeap, size, 0, offset);
- insert_at_head( &mmesa->TexObjList, t );
+ t->heap = heap;
+ t->MemBlock = mmAllocMem( mmesa->texHeap[heap], size, 0, offset);
+ if (!t->MemBlock) {
+ fprintf(stderr, "Couldn't alloc placeholder sz %x ofs %x\n",
+ (int)size, (int)offset);
+ mmDumpMemInfo( mmesa->texHeap[heap]);
+ return;
+ }
+ insert_at_head( &(mmesa->TexObjList[heap]), t );
}
}
+void mgaAgeTextures( mgaContextPtr mmesa, int heap )
+{
+ drm_mga_sarea_t *sarea = mmesa->sarea;
+ int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]);
+ int idx, nr = 0;
+
+ /* Have to go right round from the back to ensure stuff ends up
+ * LRU in our local list... Fix with a cursor pointer.
+ */
+ for (idx = sarea->texList[heap][MGA_NR_TEX_REGIONS].prev ;
+ idx != MGA_NR_TEX_REGIONS && nr < MGA_NR_TEX_REGIONS ;
+ idx = sarea->texList[heap][idx].prev, nr++)
+ {
+ if (sarea->texList[heap][idx].age > mmesa->texAge[heap]) {
+ mgaTexturesGone(mmesa, heap, idx * sz, sz, 1);
+ }
+ }
+
+ if (nr == MGA_NR_TEX_REGIONS) {
+ mgaTexturesGone(mmesa, heap, 0,
+ mmesa->mgaScreen->textureSize[heap], 0);
+ mgaResetGlobalLRU( mmesa, heap );
+ }
+
+
+ if (0) {
+ mgaPrintGlobalLRU( mmesa, heap );
+ mgaPrintLocalLRU( mmesa, heap );
+ }
+
+ mmesa->texAge[heap] = sarea->texAge[heap];
+ mmesa->dirty |= MGA_UPLOAD_TEX0IMAGE | MGA_UPLOAD_TEX1IMAGE;
+}
+
+
/*
* mgaSetTexWrappings
*/
@@ -281,22 +404,22 @@ static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4]) {
/*
- * mgaUploadSubImage
+ * mgaUploadSubImageLocked
*
* Perform an iload based update of a resident buffer. This is used for
* both initial loading of the entire image, and texSubImage updates.
*
* Performed with the hardware lock held.
*/
-static void mgaUploadSubImage( mgaContextPtr mmesa,
- mgaTextureObjectPtr t,
- int level,
- int x, int y, int width, int height ) {
+static void mgaUploadSubImageLocked( mgaContextPtr mmesa,
+ mgaTextureObjectPtr t,
+ int level,
+ int x, int y, int width, int height ) {
int x2;
int dwords;
- int dstorg;
+ int offset;
struct gl_texture_image *image;
- int texelBytes, texelsPerDword, texelMaccess;
+ int texelBytes, texelsPerDword, texelMaccess, length;
if ( level < 0 || level >= MGA_TEX_MAXLEVELS ) {
mgaMsg( 1, "mgaUploadSubImage: bad level: %i\n", level );
@@ -310,15 +433,9 @@ static void mgaUploadSubImage( mgaContextPtr mmesa,
}
/* find the proper destination offset for this level */
- dstorg = (mmesa->mgaScreen->textureOffset + t->MemBlock->ofs +
+ offset = (t->MemBlock->ofs +
t->offsets[level]);
- /* turn on PCI/AGP if needed
- if ( textureHeapPhysical ) {
- dstorg |= 1 | mgaglx.use_agp;
- }
- */
-
texelBytes = t->texelBytes;
switch( texelBytes ) {
case 1:
@@ -363,7 +480,7 @@ static void mgaUploadSubImage( mgaContextPtr mmesa,
x = (x + (texelsPerDword-1)) & ~(texelsPerDword-1);
width = x2 - x;
}
-
+
/* we may not be able to upload the entire texture in one
batch due to register limits or dma buffer limits.
Recursively split it up. */
@@ -374,7 +491,8 @@ static void mgaUploadSubImage( mgaContextPtr mmesa,
}
mgaMsg(10, "mgaUploadSubImage: recursively subdividing\n" );
- mgaUploadSubImage( mmesa, t, level, x, y, width, height >> 1 );
+ mgaUploadSubImageLocked( mmesa, t, level, x, y,
+ width, height >> 1 );
y += ( height >> 1 );
height -= ( height >> 1 );
}
@@ -385,31 +503,50 @@ static void mgaUploadSubImage( mgaContextPtr mmesa,
/* bump the performance counter */
mgaglx.c_textureSwaps += ( dwords << 2 );
-
-#if 0
-
- /* fill in the secondary buffer with properly converted texels
- from the mesa buffer */
- mgaConvertTexture( dest, texelBytes, image, x, y, width, height );
-
- /* send the secondary data */
- mgaSecondaryDma( TT_BLIT, dest, dwords );
-#endif
-
+ length = dwords * 4;
+
+ /* Fill in the secondary buffer with properly converted texels
+ * from the mesa buffer. */
+ if(t->heap == MGA_CARD_HEAP) {
+ mgaGetILoadBufferLocked( mmesa );
+ mgaConvertTexture( (mgaUI32 *)mmesa->iload_buffer->address,
+ texelBytes, image, x, y, width, height );
+ if(length < 64) length = 64;
+ mgaMsg(10, "TexelBytes : %d, offset: %d, length : %d\n",
+ texelBytes,
+ mmesa->mgaScreen->textureOffset[t->heap] +
+ offset +
+ y * width * 4/texelsPerDword,
+ length);
+
+ mgaFireILoadLocked( mmesa,
+ mmesa->mgaScreen->textureOffset[t->heap] +
+ offset +
+ y * width * 4/texelsPerDword,
+ length);
+ } else {
+ /* This works, is slower for uploads to card space and needs
+ * additional synchronization with the dma stream.
+ */
+ mgaConvertTexture( (mgaUI32 *)
+ (mmesa->mgaScreen->texVirtual[t->heap] +
+ offset +
+ y * width * 4/texelsPerDword),
+ texelBytes, image, x, y, width, height );
+ }
}
-
static void mgaUploadTexLevel( mgaContextPtr mmesa,
- mgaTextureObjectPtr t,
- int l )
+ mgaTextureObjectPtr t,
+ int l )
{
- mgaUploadSubImage( mmesa,
- t,
- l,
- 0, 0,
- t->tObj->Image[l]->Width,
- t->tObj->Image[l]->Height);
+ mgaUploadSubImageLocked( mmesa,
+ t,
+ l,
+ 0, 0,
+ t->tObj->Image[l]->Width,
+ t->tObj->Image[l]->Height);
}
@@ -527,9 +664,11 @@ static void mgaCreateTexObj(mgaContextPtr mmesa, struct gl_texture_object *tObj)
/* fill in our mga texture object */
t->tObj = tObj;
t->ctx = mmesa;
+ t->age = 0;
+ t->bound = 0;
- insert_at_tail(&(mmesa->TexObjList), t);
+ insert_at_tail(&(mmesa->SwappedOut), t);
t->MemBlock = 0;
@@ -596,34 +735,61 @@ static void mgaCreateTexObj(mgaContextPtr mmesa, struct gl_texture_object *tObj)
tObj->DriverData = t;
}
+static void mgaMigrateTexture( mgaContextPtr mmesa, mgaTextureObjectPtr t )
+{
+ /* NOT DONE */
+}
-int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t )
+static int mgaChooseTexHeap( mgaContextPtr mmesa, mgaTextureObjectPtr t )
{
+ return 0;
+}
+
+int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t )
+{
+ int heap;
int i;
int ofs;
mgaglx.c_textureSwaps++;
+ heap = t->heap = mgaChooseTexHeap( mmesa, t );
+
/* Do we need to eject LRU texture objects?
*/
if (!t->MemBlock) {
while (1)
{
- t->MemBlock = mmAllocMem( mmesa->texHeap, t->totalSize, 12, 0 );
+ mgaTextureObjectPtr tmp = mmesa->TexObjList[heap].prev;
+
+ t->MemBlock = mmAllocMem( mmesa->texHeap[heap],
+ t->totalSize,
+ 6, 0 );
if (t->MemBlock)
break;
- if (mmesa->TexObjList.prev == &(mmesa->TexObjList)) {
- fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize);
- mmDumpMemInfo( mmesa->texHeap );
+ if (mmesa->TexObjList[heap].prev->bound) {
+ fprintf(stderr,
+ "Hit bound texture in upload\n");
return -1;
}
- mgaDestroyTexObj( mmesa, mmesa->TexObjList.prev );
+ if (mmesa->TexObjList[heap].prev ==
+ &(mmesa->TexObjList[heap]))
+ {
+ fprintf(stderr, "Failed to upload texture, "
+ "sz %d\n", t->totalSize);
+ mmDumpMemInfo( mmesa->texHeap[heap] );
+ return -1;
+ }
+
+ mgaDestroyTexObj( mmesa, tmp );
}
- ofs = t->MemBlock->ofs;
+ ofs = t->MemBlock->ofs
+ + mmesa->mgaScreen->textureOffset[heap]
+ ;
t->Setup[MGA_TEXREG_ORG] = ofs;
t->Setup[MGA_TEXREG_ORG1] = ofs + t->offsets[1];
@@ -638,8 +804,16 @@ int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t )
*/
mgaUpdateTexLRU( mmesa, t );
+
+ if (MGA_DEBUG&DEBUG_VERBOSE_LRU)
+ fprintf(stderr, "dispatch age: %d age freed memory: %d\n",
+ GET_DISPATCH_AGE(mmesa), mmesa->dirtyAge);
+
+ if (mmesa->dirtyAge >= GET_DISPATCH_AGE(mmesa))
+ mgaWaitAgeLocked( mmesa, mmesa->dirtyAge );
+
if (t->dirty_images) {
- if (MGA_DEBUG & MGA_DEBUG_VERBOSE_MSG)
+ if (MGA_DEBUG&DEBUG_VERBOSE_LRU)
fprintf(stderr, "*");
for (i = 0 ; i <= t->lastLevel ; i++)
@@ -692,12 +866,10 @@ static void mgaUpdateTextureEnvG200( GLcontext *ctx )
}
}
-/* I don't have the alpha values correct yet:
- */
static void mgaUpdateTextureStage( GLcontext *ctx, int unit )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- mgaUI32 *reg = &mmesa->Setup[MGA_CTXREG_TDUAL0 + unit];
+ GLuint *reg = &mmesa->Setup[MGA_CTXREG_TDUAL0 + unit];
GLuint source = mmesa->tmu_source[unit];
struct gl_texture_object *tObj = ctx->Texture.Unit[source].Current;
@@ -725,13 +897,13 @@ static void mgaUpdateTextureStage( GLcontext *ctx, int unit )
*reg = ( TD0_color_arg2_diffuse |
TD0_color_sel_mul |
TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_arg1);
+ TD0_alpha_sel_mul);
else
*reg = ( TD0_color_arg2_prevstage |
TD0_color_alpha_prevstage |
TD0_color_sel_mul |
TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_arg1);
+ TD0_alpha_sel_mul);
break;
case GL_DECAL:
*reg = (TD0_color_arg2_fcol |
@@ -751,20 +923,49 @@ static void mgaUpdateTextureStage( GLcontext *ctx, int unit )
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_arg1);
+ TD0_alpha_sel_add);
else
*reg = ( TD0_color_arg2_prevstage |
TD0_color_alpha_prevstage |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_arg1);
+ TD0_alpha_sel_add);
break;
case GL_BLEND:
- /* Use a multipass mechanism to do this:
+ if (0)
+ fprintf(stderr, "GL_BLEND unit %d flags %x\n", unit,
+ mmesa->blend_flags);
+
+ if (mmesa->blend_flags)
+ mmesa->Fallback |= MGA_FALLBACK_TEXTURE;
+ return;
+
+ /* Do singletexture GL_BLEND with 'all ones' env-color
+ * by using both texture units. Multitexture gl_blend
+ * is a fallback.
*/
- mmesa->Fallback |= MGA_FALLBACK_TEXTURE;
+ if (unit == 0) {
+ /* Part 1: R1 = Rf ( 1 - Rt )
+ * A1 = Af At
+ */
+ *reg = ( TD0_color_arg2_diffuse |
+ TD0_color_arg1_inv_enable |
+ TD0_color_sel_mul |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_arg1);
+ } else {
+ /* Part 2: R2 = R1 + Rt
+ * A2 = A1
+ */
+ *reg = ( TD0_color_arg2_prevstage |
+ TD0_color_add_add |
+ TD0_color_sel_add |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_arg2);
+ }
+
break;
default:
}
@@ -782,9 +983,8 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) {
mgaMsg(15,"mgaUpdateTextureState %d\n", unit);
/* disable texturing until it is known to be good */
- mmesa->Setup[MGA_CTXREG_DWGCTL] =
- (( mmesa->Setup[MGA_CTXREG_DWGCTL] & DC_opcod_MASK ) |
- DC_opcod_trap);
+ mmesa->Setup[MGA_CTXREG_DWGCTL] &= DC_opcod_MASK;
+ mmesa->Setup[MGA_CTXREG_DWGCTL] |= DC_opcod_trap;
enabled = (ctx->Texture.Enabled>>(source*4))&TEXTURE0_ANY;
if (enabled != TEXTURE0_2D) {
@@ -797,6 +997,8 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) {
if ( !tObj || tObj != ctx->Texture.Unit[source].CurrentD[2] )
return;
+
+/* fprintf(stderr, "unit %d: %d\n", unit, tObj->Name); */
/* if the texture object doesn't exist at all (never used or
swapped out), create it now, uploading all texture images */
@@ -804,7 +1006,6 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) {
if ( !tObj->DriverData ) {
/* clear the current pointer so that texture object can be
swapped out if necessary to make room */
- mmesa->CurrentTexObj[source] = NULL;
mgaCreateTexObj( mmesa, tObj );
if ( !tObj->DriverData ) {
@@ -815,9 +1016,8 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) {
}
/* we definately have a valid texture now */
- mmesa->Setup[MGA_CTXREG_DWGCTL] =
- (( mmesa->Setup[MGA_CTXREG_DWGCTL] & DC_opcod_MASK ) |
- DC_opcod_texture_trap);
+ mmesa->Setup[MGA_CTXREG_DWGCTL] &= DC_opcod_MASK;
+ mmesa->Setup[MGA_CTXREG_DWGCTL] |= DC_opcod_texture_trap;
t = (mgaTextureObjectPtr)tObj->DriverData;
@@ -825,6 +1025,11 @@ static void mgaUpdateTextureObject( GLcontext *ctx, int unit ) {
mmesa->dirty |= (MGA_UPLOAD_TEX0IMAGE << unit);
mmesa->CurrentTexObj[unit] = t;
+ t->bound = unit+1;
+
+ if (t->MemBlock)
+ mgaUpdateTexLRU( mmesa, t );
+
t->Setup[MGA_TEXREG_CTL2] &= ~TMC_dualtex_enable;
if (ctx->Texture.Enabled == (TEXTURE0_2D|TEXTURE1_2D))
@@ -848,23 +1053,31 @@ void mgaUpdateTextureState( GLcontext *ctx )
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
mmesa->Fallback &= ~MGA_FALLBACK_TEXTURE;
+ if (mmesa->CurrentTexObj[0]) mmesa->CurrentTexObj[0]->bound = 0;
+ if (mmesa->CurrentTexObj[1]) mmesa->CurrentTexObj[1]->bound = 0;
+ mmesa->CurrentTexObj[0] = 0;
+ mmesa->CurrentTexObj[1] = 0;
+
if (MGA_IS_G400(mmesa)) {
mgaUpdateTextureObject( ctx, 0 );
mgaUpdateTextureStage( ctx, 0 );
- mmesa->Setup[MGA_CTXREG_TDUAL1] = mmesa->Setup[MGA_CTXREG_TDUAL0];
+ mmesa->Setup[MGA_CTXREG_TDUAL1] =
+ mmesa->Setup[MGA_CTXREG_TDUAL0];
if (mmesa->multitex) {
mgaUpdateTextureObject( ctx, 1 );
mgaUpdateTextureStage( ctx, 1 );
}
+
+ mmesa->dirty |= MGA_UPLOAD_TEX0 | MGA_UPLOAD_TEX1;
} else {
mgaUpdateTextureObject( ctx, 0 );
- mgaUpdateTextureEnvG200( ctx );
+ mgaUpdateTextureEnvG200( ctx );
}
/* schedule the register writes */
- mmesa->dirty |= MGA_UPLOAD_CTX;
+ mmesa->dirty |= MGA_UPLOAD_CTX | MGA_UPLOAD_TEX0;
}
@@ -880,14 +1093,57 @@ Driver functions called directly from mesa
/*
* mgaTexEnv
*/
-void mgaTexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param ) {
+void mgaTexEnv( GLcontext *ctx, GLenum pname, const GLfloat *param )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
mgaMsg( 10, "mgaTexEnv( %i )\n", pname );
+
if (pname == GL_TEXTURE_ENV_MODE) {
/* force the texture state to be updated */
- MGA_CONTEXT(ctx)->CurrentTexObj[0] = 0;
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
}
+ else if (pname == GL_TEXTURE_ENV_COLOR)
+ {
+ struct gl_texture_unit *texUnit =
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ GLfloat *fc = texUnit->EnvColor;
+ GLubyte c[4];
+ GLuint col;
+
+
+ c[0] = fc[0];
+ c[1] = fc[1];
+ c[2] = fc[2];
+ c[3] = fc[3];
+
+ /* No alpha at 16bpp?
+ */
+ col = mgaPackColor( mmesa->mgaScreen->Attrib,
+ c[0], c[1], c[2], c[3] );
+
+ mmesa->envcolor = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]);
+
+ if (mmesa->Setup[MGA_CTXREG_FCOL] != col) {
+ FLUSH_BATCH(mmesa);
+ mmesa->Setup[MGA_CTXREG_FCOL] = col;
+ mmesa->dirty |= MGA_UPLOAD_CTX;
+
+ mmesa->blend_flags &= ~MGA_BLEND_ENV_COLOR;
+
+ /* Actually just require all four components to be
+ * equal. This permits a single-pass GL_BLEND.
+ *
+ * More complex multitexture/multipass fallbacks
+ * for blend can be done later.
+ */
+ if (mmesa->envcolor != 0x0 &&
+ mmesa->envcolor != 0xffffffff)
+ mmesa->blend_flags |= MGA_BLEND_ENV_COLOR;
+ }
+ }
+
}
/*
@@ -907,6 +1163,7 @@ void mgaTexImage( GLcontext *ctx, GLenum target,
mgaUpdateTextureState time. */
t = (mgaTextureObjectPtr) tObj->DriverData;
if ( t ) {
+ if (t->bound) FLUSH_BATCH(mmesa);
/* if this is the current object, it will force an update */
mgaDestroyTexObj( mmesa, t );
mmesa->new_state |= MGA_NEW_TEXTURE;
@@ -936,6 +1193,7 @@ void mgaTexSubImage( GLcontext *ctx, GLenum target,
mgaUpdateTextureState time. */
t = (mgaTextureObjectPtr) tObj->DriverData;
if ( t ) {
+ if (t->bound) FLUSH_BATCH(mmesa);
/* if this is the current object, it will force an update */
mgaDestroyTexObj( mmesa, t );
mmesa->new_state |= MGA_NEW_TEXTURE;
@@ -956,7 +1214,9 @@ void mgaTexSubImage( GLcontext *ctx, GLenum target,
*/
void mgaTexParameter( GLcontext *ctx, GLenum target,
struct gl_texture_object *tObj,
- GLenum pname, const GLfloat *params ) {
+ GLenum pname, const GLfloat *params )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
mgaTextureObjectPtr t;
mgaMsg( 10, "mgaTexParameter( %p, %i )\n", tObj, pname );
@@ -973,52 +1233,68 @@ void mgaTexParameter( GLcontext *ctx, GLenum target,
switch (pname) {
case GL_TEXTURE_MIN_FILTER:
case GL_TEXTURE_MAG_FILTER:
+ if (t->bound) FLUSH_BATCH(mmesa);
mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
break;
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
+ if (t->bound) FLUSH_BATCH(mmesa);
mgaSetTexWrapping(t,tObj->WrapS,tObj->WrapT);
break;
case GL_TEXTURE_BORDER_COLOR:
+ if (t->bound) FLUSH_BATCH(mmesa);
mgaSetTexBorderColor(t,tObj->BorderColor);
break;
default:
return;
}
- /* force the texture state to be updated */
- MGA_CONTEXT(ctx)->CurrentTexObj[0] = NULL;
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
+
+ mmesa->new_state |= MGA_NEW_TEXTURE;
}
/*
* mgaBindTexture
*/
void mgaBindTexture( GLcontext *ctx, GLenum target,
- struct gl_texture_object *tObj ) {
+ struct gl_texture_object *tObj )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
mgaMsg( 10, "mgaBindTexture( %p )\n", tObj );
-
+
+ FLUSH_BATCH(mmesa);
+
+ if (mmesa->CurrentTexObj[ctx->Texture.CurrentUnit]) {
+ mmesa->CurrentTexObj[ctx->Texture.CurrentUnit]->bound = 0;
+ mmesa->CurrentTexObj[ctx->Texture.CurrentUnit] = 0;
+ }
+
/* force the texture state to be updated
*/
- MGA_CONTEXT(ctx)->CurrentTexObj[0] = NULL;
MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
}
/*
* mgaDeleteTexture
*/
-void mgaDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) {
+void mgaDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ mgaTextureObjectPtr t = (mgaTextureObjectPtr)tObj->DriverData;
mgaMsg( 10, "mgaDeleteTexture( %p )\n", tObj );
- /* delete our driver data */
- if ( tObj->DriverData ) {
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- mgaDestroyTexObj( mmesa,
- (mgaTextureObjectPtr)(tObj->DriverData) );
+ if ( t ) {
+ if (t->bound) {
+ FLUSH_BATCH(mmesa);
+ mmesa->CurrentTexObj[t->bound-1] = 0;
+ mmesa->new_state |= MGA_NEW_TEXTURE;
+ }
+
+ mgaDestroyTexObj( mmesa, t );
mmesa->new_state |= MGA_NEW_TEXTURE;
}
}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.c b/xc/lib/GL/mesa/src/drv/mga/mgatris.c
index bd8ef083f..387a79f3e 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgatris.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.c
@@ -27,6 +27,7 @@
#include <stdio.h>
#include <math.h>
+#include "types.h"
#include "vb.h"
#include "pipeline.h"
@@ -122,34 +123,14 @@ void mgaDDTrifuncInit()
init_twoside_offset();
init_twoside_offset_flat();
- /* Hmmm...
- */
- for (i = 0 ; i < 0x20 ; i++) {
- if (i & ~MGA_FLAT_BIT) {
- points_tab[i] = points_tab[i&MGA_FLAT_BIT];
- line_tab[i] = line_tab[i&MGA_FLAT_BIT];
- }
- }
-
for (i = 0 ; i < 0x20 ; i++)
- if ((i & (MGA_NODRAW_BIT|MGA_FALLBACK_BIT)) == MGA_NODRAW_BIT ||
- mgaglx.nullprims)
+ if ((i & (MGA_NODRAW_BIT|MGA_FALLBACK_BIT)) == MGA_NODRAW_BIT)
{
quad_tab[i] = mga_null_quad;
tri_tab[i] = mga_null_triangle;
line_tab[i] = mga_null_line;
points_tab[i] = mga_null_points;
}
-
- if (mgaglx.noFallback) {
- for (i = 0 ; i < 0x10 ; i++) {
- points_tab[i|MGA_FALLBACK_BIT] = points_tab[i];
- line_tab[i|MGA_FALLBACK_BIT] = line_tab[i];
- tri_tab[i|MGA_FALLBACK_BIT] = tri_tab[i];
- quad_tab[i|MGA_FALLBACK_BIT] = quad_tab[i];
- }
- }
-
}
@@ -162,50 +143,61 @@ void mgaDDChooseRenderState( GLcontext *ctx )
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
GLuint flags = ctx->TriangleCaps;
- ctx->IndirectTriangles &= ~DD_SW_RASTERIZE;
+ if (mmesa->Fallback)
+ return;
+
+ mmesa->IndirectTriangles = 0;
if (flags) {
GLuint ind = 0;
GLuint shared = 0;
- GLuint fallback = MGA_FALLBACK_BIT;
-
- if (mgaglx.noFallback) fallback = 0;
if (flags & DD_Z_NEVER) shared |= MGA_NODRAW_BIT;
if (flags & DD_FLATSHADE) shared |= MGA_FLAT_BIT;
- if (flags & DD_MULTIDRAW) shared |= fallback;
- if (flags & (DD_SELECT|DD_FEEDBACK)) shared |= MGA_FALLBACK_BIT;
+ if (flags & (DD_MULTIDRAW|
+ DD_SELECT|
+ DD_FEEDBACK)) shared |= MGA_FALLBACK_BIT;
if (flags & DD_STENCIL) shared |= MGA_FALLBACK_BIT;
ind = shared;
+#if 0
if (flags & DD_POINT_SMOOTH) ind |= MGA_ANTIALIAS_BIT;
- if (flags & DD_POINT_ATTEN) ind |= fallback;
+#else
+ if (flags & DD_POINT_SMOOTH) ind |= MGA_FALLBACK_BIT;
+#endif
mmesa->renderindex = ind;
mmesa->PointsFunc = points_tab[ind];
if (ind & MGA_FALLBACK_BIT)
- ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE;
+ mmesa->IndirectTriangles |= DD_POINT_SW_RASTERIZE;
ind = shared;
+#if 0
if (flags & DD_LINE_SMOOTH) ind |= MGA_ANTIALIAS_BIT;
- if (flags & DD_LINE_STIPPLE) ind |= fallback;
+#else
+ if (flags & DD_LINE_SMOOTH) ind |= MGA_FALLBACK_BIT;
+#endif
+ if (flags & DD_LINE_STIPPLE) ind |= MGA_FALLBACK_BIT;
mmesa->renderindex |= ind;
mmesa->LineFunc = line_tab[ind];
if (ind & MGA_FALLBACK_BIT)
- ctx->IndirectTriangles |= DD_LINE_SW_RASTERIZE;
+ mmesa->IndirectTriangles |= DD_LINE_SW_RASTERIZE;
ind = shared;
if (flags & DD_TRI_SMOOTH) ind |= MGA_ANTIALIAS_BIT;
if (flags & DD_TRI_OFFSET) ind |= MGA_OFFSET_BIT;
if (flags & DD_TRI_LIGHT_TWOSIDE) ind |= MGA_TWOSIDE_BIT;
- if (flags & (DD_TRI_UNFILLED|DD_TRI_STIPPLE)) ind |= fallback;
+ if (flags & DD_TRI_UNFILLED) ind |= MGA_FALLBACK_BIT;
+ if ((flags & DD_TRI_STIPPLE) &&
+ (ctx->IndirectTriangles & DD_TRI_STIPPLE)) ind |= MGA_FALLBACK_BIT;
mmesa->renderindex |= ind;
mmesa->TriangleFunc = tri_tab[ind];
mmesa->QuadFunc = quad_tab[ind];
if (ind & MGA_FALLBACK_BIT)
- ctx->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | DD_QUAD_SW_RASTERIZE);
+ mmesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE |
+ DD_QUAD_SW_RASTERIZE);
}
else if (mmesa->renderindex)
{
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h b/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h
index ac5a545d2..2a9d16b86 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h
+++ b/xc/lib/GL/mesa/src/drv/mga/mgatritmp.h
@@ -98,19 +98,31 @@ static void TAG(quad)( GLcontext *ctx, GLuint v0,
}
-#if ((IND & ~MGA_FLAT_BIT) == 0)
-
static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
mgaVertexPtr mgaVB = MGA_DRIVER_DATA(ctx->VB)->verts;
float width = ctx->Line.Width;
- if (IND & MGA_FLAT_BIT) {
+ if (IND & (MGA_TWOSIDE_BIT|MGA_FLAT_BIT)) {
mgaVertex tmp0 = mgaVB[v0];
mgaVertex tmp1 = mgaVB[v1];
- *(int *)&tmp0.warp1.color = *(int *)&mgaVB[pv].warp1.color;
- *(int *)&tmp1.warp1.color = *(int *)&mgaVB[pv].warp1.color;
+
+ if (IND & MGA_TWOSIDE_BIT) {
+ GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data;
+
+ if (IND & MGA_FLAT_BIT) {
+ MGA_COLOR((char *)&tmp0.warp1.color,vbcolor[pv]);
+ *(int *)&tmp1.warp1.color = *(int *)&tmp0.warp1.color;
+ } else {
+ MGA_COLOR((char *)&tmp0.warp1.color,vbcolor[v0]);
+ MGA_COLOR((char *)&tmp1.warp1.color,vbcolor[v1]);
+ }
+
+ } else {
+ *(int *)&tmp0.warp1.color = *(int *)&mgaVB[pv].warp1.color;
+ *(int *)&tmp1.warp1.color = *(int *)&mgaVB[pv].warp1.color;
+ }
mga_draw_line( mmesa, &tmp0, &tmp1, width );
}
else
@@ -125,13 +137,20 @@ static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last )
mgaVertexPtr mgaVB = MGA_DRIVER_DATA(VB)->verts;
GLfloat sz = ctx->Point.Size * .5;
int i;
-
+
for(i=first;i<=last;i++)
- if(VB->ClipMask[i]==0)
- mga_draw_point( mmesa, &mgaVB[i], sz );
+ if(VB->ClipMask[i]==0) {
+ if (IND & MGA_TWOSIDE_BIT) {
+ GLubyte (*vbcolor)[4] = VB->ColorPtr->data;
+ mgaVertex tmp0 = mgaVB[i];
+ MGA_COLOR((char *)&tmp0.warp1.color, vbcolor[i]);
+ mga_draw_point( mmesa, &tmp0, sz );
+ } else
+ mga_draw_point( mmesa, &mgaVB[i], sz );
+ }
}
-#endif
+
static void TAG(init)( void )
@@ -139,10 +158,9 @@ static void TAG(init)( void )
tri_tab[IND] = TAG(triangle);
quad_tab[IND] = TAG(quad);
-#if ((IND & ~MGA_FLAT_BIT) == 0)
line_tab[IND] = TAG(line);
points_tab[IND] = TAG(points);
-#endif
+
}
diff --git a/xc/lib/GL/mesa/src/drv/mga/mgavb.c b/xc/lib/GL/mesa/src/drv/mga/mgavb.c
index 4772e8a34..3f246d9a7 100644
--- a/xc/lib/GL/mesa/src/drv/mga/mgavb.c
+++ b/xc/lib/GL/mesa/src/drv/mga/mgavb.c
@@ -104,7 +104,7 @@ static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \
GLfloat yoffset = mmesa->driDrawable->h + mmesa->drawY + SUBPIXEL_Y; \
int i; \
(void) xoffset; (void) yoffset; \
- \
+ if (0) fprintf(stderr, "V"); \
gl_import_client_data( VB, VB->ctx->RenderFlags, \
(VB->ClipOrMask \
? VEC_WRITABLE|VEC_GOOD_STRIDE \
diff --git a/xc/lib/GL/mesa/src/drv/r128/Imakefile b/xc/lib/GL/mesa/src/drv/r128/Imakefile
new file mode 100644
index 000000000..4cd07b8ff
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/Imakefile
@@ -0,0 +1,325 @@
+XCOMM $XFree86$
+
+#include <Threads.tmpl>
+
+#define DoNormalLib NormalLibGlx
+#define DoSharedLib SharedLibGlx
+#define DoExtraLib SharedLibGlx
+#define DoDebugLib DebugLibGlx
+#define DoProfileLib ProfileLibGlx
+
+#if Malloc0ReturnsNull
+ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
+#endif
+
+#if BuildXF86DRI
+ DRI_DEFINES = GlxDefines -DDRIVERTS
+ DRI_INCLUDES = -I../../../../dri \
+ -I../../../../glx \
+ -I../../../dri \
+ -I$(TOP)/include \
+ -I$(TOP)/include/GL \
+ -I$(XF86OSSRC) \
+ -I$(XF86COMSRC) \
+ -I$(SERVERSRC)/GL/dri \
+ -I$(XF86DRIVERSRC)/r128 \
+ -I../../../include \
+ -I../.. \
+ -I../../X \
+ -I../common
+#endif
+
+LinkSourceFile(mm.c, ../common)
+LinkSourceFile(mm.h, ../common)
+LinkSourceFile(hwlog.c, ../common)
+LinkSourceFile(hwlog.h, ../common)
+
+MESA_INCLUDES = -I. -I.. -I../../include
+
+ DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES)
+ INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES)
+
+ R128SRCS = r128_cce.c \
+ r128_clear.c \
+ r128_context.c \
+ r128_dd.c \
+ r128_fastpath.c \
+ r128_pipeline.c \
+ r128_screen.c \
+ r128_span.c \
+ r128_state.c \
+ r128_swap.c \
+ r128_tex.c \
+ r128_tris.c \
+ r128_vb.c \
+ r128_xmesa.c
+
+ R128OBJS = r128_cce.o \
+ r128_clear.o \
+ r128_context.o \
+ r128_dd.o \
+ r128_fastpath.o \
+ r128_pipeline.o \
+ r128_screen.o \
+ r128_span.o \
+ r128_state.o \
+ r128_swap.o \
+ r128_tex.o \
+ r128_tris.o \
+ r128_vb.o \
+ r128_xmesa.o
+
+#if !GlxUseBuiltInDRIDriver
+ DRISRCS = ../../../dri/dri_mesa.c \
+ ../../../../dri/dri_tmm.c
+
+ DRIOBJS = ../../../dri/dri_mesa.o \
+ ../../../../dri/dri_tmm.o
+
+ DRMSRCS = ../../../../dri/drm/xf86drm.c \
+ ../../../../dri/drm/xf86drmHash.c \
+ ../../../../dri/drm/xf86drmRandom.c \
+ ../../../../dri/drm/xf86drmSL.c \
+ ../../../../dri/drm/xf86drmR128.c
+
+ DRMOBJS = ../../../../dri/drm/xf86drm.o \
+ ../../../../dri/drm/xf86drmHash.o \
+ ../../../../dri/drm/xf86drmRandom.o \
+ ../../../../dri/drm/xf86drmSL.o \
+ ../../../../dri/drm/xf86drmR128.o
+
+ MESASRCS = ../../aatriangle.c \
+ ../../accum.c \
+ ../../alpha.c \
+ ../../alphabuf.c \
+ ../../attrib.c \
+ ../../bbox.c \
+ ../../bitmap.c \
+ ../../blend.c \
+ ../../buffers.c \
+ ../../clip.c \
+ ../../colortab.c \
+ ../../config.c \
+ ../../context.c \
+ ../../copypix.c \
+ ../../cva.c \
+ ../../debug_xform.c \
+ ../../depth.c \
+ ../../dlist.c \
+ ../../drawpix.c \
+ ../../enable.c \
+ ../../enums.c \
+ ../../eval.c \
+ ../../extensions.c \
+ ../../feedback.c \
+ ../../fog.c \
+ ../../get.c \
+ ../../glapi.c \
+ ../../glapinoop.c \
+ ../../glthread.c \
+ ../../hash.c \
+ ../../image.c \
+ ../../imaging.c \
+ ../../light.c \
+ ../../lines.c \
+ ../../logic.c \
+ ../../masking.c \
+ ../../matrix.c \
+ ../../mem.c \
+ ../../mmath.c \
+ ../../pb.c \
+ ../../pipeline.c \
+ ../../pixel.c \
+ ../../pixeltex.c \
+ ../../points.c \
+ ../../polygon.c \
+ ../../quads.c \
+ ../../rastpos.c \
+ ../../readpix.c \
+ ../../rect.c \
+ ../../scissor.c \
+ ../../shade.c \
+ ../../span.c \
+ ../../stages.c \
+ ../../state.c \
+ ../../stencil.c \
+ ../../teximage.c \
+ ../../texobj.c \
+ ../../texstate.c \
+ ../../texture.c \
+ ../../texutil.c \
+ ../../translate.c \
+ ../../triangle.c \
+ ../../varray.c \
+ ../../vb.c \
+ ../../vbcull.c \
+ ../../vbfill.c \
+ ../../vbindirect.c \
+ ../../vbrender.c \
+ ../../vbxform.c \
+ ../../vector.c \
+ ../../vertices.c \
+ ../../winpos.c \
+ ../../xform.c \
+ ../../zoom.c \
+ ../../X86/common_x86.c
+
+ MESAOBJS = ../../aatriangle.o \
+ ../../accum.o \
+ ../../alpha.o \
+ ../../alphabuf.o \
+ ../../attrib.o \
+ ../../bbox.o \
+ ../../bitmap.o \
+ ../../blend.o \
+ ../../buffers.o \
+ ../../clip.o \
+ ../../colortab.o \
+ ../../config.o \
+ ../../context.o \
+ ../../copypix.o \
+ ../../cva.o \
+ ../../debug_xform.o \
+ ../../depth.o \
+ ../../dlist.o \
+ ../../drawpix.o \
+ ../../enable.o \
+ ../../enums.o \
+ ../../eval.o \
+ ../../extensions.o \
+ ../../feedback.o \
+ ../../fog.o \
+ ../../get.o \
+ ../../hash.o \
+ ../../hint.o \
+ ../../image.o \
+ ../../imaging.o \
+ ../../light.o \
+ ../../lines.o \
+ ../../logic.o \
+ ../../masking.o \
+ ../../matrix.o \
+ ../../mem.o \
+ ../../mmath.o \
+ ../../pb.o \
+ ../../pipeline.o \
+ ../../pixel.o \
+ ../../pixeltex.o \
+ ../../points.o \
+ ../../polygon.o \
+ ../../quads.o \
+ ../../rastpos.o \
+ ../../readpix.o \
+ ../../rect.o \
+ ../../scissor.o \
+ ../../shade.o \
+ ../../span.o \
+ ../../stages.o \
+ ../../state.o \
+ ../../stencil.o \
+ ../../teximage.o \
+ ../../texobj.o \
+ ../../texstate.o \
+ ../../texture.o \
+ ../../texutil.o \
+ ../../translate.o \
+ ../../triangle.o \
+ ../../varray.o \
+ ../../vb.o \
+ ../../vbcull.o \
+ ../../vbfill.o \
+ ../../vbindirect.o \
+ ../../vbrender.o \
+ ../../vbxform.o \
+ ../../vector.o \
+ ../../vertices.o \
+ ../../winpos.o \
+ ../../xform.o \
+ ../../zoom.o
+
+#ifdef i386Architecture
+ X86_SRCS = ../../X86/x86.c \
+ ../../X86/x86a.S \
+ ../../X86/common_x86.c \
+ ../../X86/common_x86asm.S \
+ ../../X86/vertex.S
+
+ X86_OBJS = ../../X86/x86.o \
+ ../../X86/x86a.o \
+ ../../X86/common_x86.o \
+ ../../X86/common_x86asm.o \
+ ../../X86/vertex.o
+
+ MMX_SRCS = ../../X86/mmx_blend.S
+
+ MMX_OBJS = ../../X86/mmx_blend.o
+
+XCOMM Disabling 3Dnow code for the time being.
+#if 0
+ 3DNOW_SRCS = ../../X86/3dnow.c \
+ ../../X86/3dnow_norm_raw.S \
+ ../../X86/3dnow_xform_masked1.S \
+ ../../X86/3dnow_xform_masked2.S \
+ ../../X86/3dnow_xform_masked3.S \
+ ../../X86/3dnow_xform_masked4.S \
+ ../../X86/3dnow_xform_raw1.S \
+ ../../X86/3dnow_xform_raw2.S \
+ ../../X86/3dnow_xform_raw3.S \
+ ../../X86/3dnow_xform_raw4.S \
+ ../../X86/vertex_3dnow.S
+
+ 3DNOW_OBJS = ../../X86/3dnow.o \
+ ../../X86/3dnow_norm_raw.o \
+ ../../X86/3dnow_xform_masked1.o \
+ ../../X86/3dnow_xform_masked2.o \
+ ../../X86/3dnow_xform_masked3.o \
+ ../../X86/3dnow_xform_masked4.o \
+ ../../X86/3dnow_xform_raw1.o \
+ ../../X86/3dnow_xform_raw2.o \
+ ../../X86/3dnow_xform_raw3.o \
+ ../../X86/3dnow_xform_raw4.o \
+ ../../X86/vertex_3dnow.o
+#endif
+
+#endif
+#endif
+
+ ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS)
+ ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS)
+
+ COMMONSRCS = mm.c hwlog.c
+ COMMONOBJS = mm.o hwlog.o
+
+ SRCS = $(DRISRCS) $(DRMSRCS) $(MESASRCS) $(ASMSRCS) \
+ $(COMMONSRCS) $(R128SRCS)
+ OBJS = $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) $(ASMOBJS) \
+ $(COMMONOBJS) $(R128OBJS)
+
+REQUIREDLIBS += -lm
+#if !GlxBuiltInMga
+REQUIREDLIBS += -L../../../.. -lGL
+#endif
+
+#if !GlxUseBuiltInDRIDriver
+#undef DoNormalLib NormalLibGlx
+#undef DoExtraLib SharedLibGlx
+#undef DoDebugLib DebugLibGlx
+#undef DoProfileLib ProfileLibGlx
+#endif
+
+#include <Library.tmpl>
+
+LibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+NormalLintTarget($(SRCS))
+
+#if !GlxUseBuiltInDRIDriver
+LIBNAME = r128_dri.so
+ALL_OBJS = $(OBJS)
+ALL_DEPS = DONE
+SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS))
+InstallDynamicModule($(LIBNAME),$(MODULEDIR)/dri,.)
+#endif
+
+DependTarget()
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_cce.c b/xc/lib/GL/mesa/src/drv/r128/r128_cce.c
new file mode 100644
index 000000000..e949dd37c
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_cce.c
@@ -0,0 +1,389 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+
+#if USE_USER_SPACE_RING
+
+#define USE_IOCTLS 0
+#define DO_SECURITY_CHECK 1
+#define R128_TIMEOUT 2000000
+
+#if DEBUG
+static void r128RingStatus(r128ScreenPtr pScrn)
+{
+ unsigned char *R128MMIO = pScrn->mmio;
+
+ R128_DEBUG(("GUI_STAT = 0x%08x\n",
+ (unsigned int)INREG(R128_GUI_STAT)));
+ R128_DEBUG(("PM4_STAT = 0x%08x\n",
+ (unsigned int)INREG(R128_PM4_STAT)));
+ R128_DEBUG(("PM4_BUFFER_DL_WPTR = 0x%08x\n",
+ (unsigned int)INREG(R128_PM4_BUFFER_DL_WPTR)));
+ R128_DEBUG(("PM4_BUFFER_DL_RPTR = 0x%08x\n",
+ (unsigned int)INREG(R128_PM4_BUFFER_DL_RPTR)));
+ R128_DEBUG(("ringWrite = 0x%08x\n", pScrn->SAREA->ringWrite));
+ R128_DEBUG(("*ringReadPtr = 0x%08x\n", *pScrn->ringReadPtr));
+}
+#endif
+
+/* FIXME: Requires access to secure registers */
+static int INPLL(r128ScreenPtr pScrn, int addr)
+{
+ unsigned char *R128MMIO = pScrn->mmio;
+
+ OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x1f);
+ return INREG(R128_CLOCK_CNTL_DATA);
+}
+
+/* FIXME: Requires access to secure registers */
+static void r128EngineFlush(r128ScreenPtr pScrn)
+{
+ unsigned char *R128MMIO = pScrn->mmio;
+ int i;
+
+ OUTREGP(R128_PC_NGUI_CTLSTAT, R128_PC_FLUSH_ALL, ~R128_PC_FLUSH_ALL);
+ for (i = 0; i < R128_TIMEOUT; i++) {
+ if (!(INREG(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) break;
+ }
+}
+
+/* FIXME: Requires access to secure registers */
+static void r128EngineReset(r128ScreenPtr pScrn)
+{
+#if USE_IOCTLS
+#if DEBUG
+ r128RingStatus(pScrn);
+#endif
+
+ (void)drmR128EngineReset(pScrn->driScreen->fd);
+#else
+ unsigned char *R128MMIO = pScrn->mmio;
+ CARD32 clock_cntl_index;
+ CARD32 mclk_cntl;
+ CARD32 gen_reset_cntl;
+
+#if DEBUG
+ r128RingStatus(pScrn);
+#endif
+
+ r128EngineFlush(pScrn);
+
+ clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX);
+ mclk_cntl = INPLL(pScrn, R128_MCLK_CNTL);
+
+ OUTPLL(R128_MCLK_CNTL, mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CPP);
+
+ gen_reset_cntl = INREG(R128_GEN_RESET_CNTL);
+
+ OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI);
+ INREG(R128_GEN_RESET_CNTL);
+ OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI);
+ INREG(R128_GEN_RESET_CNTL);
+
+ OUTPLL(R128_MCLK_CNTL, mclk_cntl);
+ OUTREG(R128_CLOCK_CNTL_INDEX, clock_cntl_index);
+ OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl);
+
+ /* Reset the ring buffer status */
+ if (R128CCE_USE_RING_BUFFER(pScrn->CCEMode)) {
+ OUTREG(R128_PM4_BUFFER_DL_WPTR, 0);
+ OUTREG(R128_PM4_BUFFER_DL_RPTR, 0);
+ pScrn->SAREA->ringWrite = 0;
+ *pScrn->ringReadPtr = 0;
+ }
+#endif
+ fprintf(stderr, "Error: Rage 128 timed out... exiting\n");
+ exit(-1);
+}
+
+#define r128CCEWaitForFifo(pScrn, entries) \
+do { \
+ if (pScrn->CCEFifoSlots < entries) \
+ r128CCEWaitForFifoFunction(pScrn, entries); \
+ pScrn->CCEFifoSlots -= entries; \
+} while (0)
+
+/* Wait for at least `entries' slots are free. The actual number of
+ slots available is stored in info->CCEFifoSize. */
+static void r128CCEWaitForFifoFunction(r128ScreenPtr pScrn, int entries)
+{
+ unsigned char *R128MMIO = pScrn->mmio;
+ int i;
+
+ for (;;) {
+ for (i = 0; i < R128_TIMEOUT; i++) {
+ pScrn->CCEFifoSlots = INREG(R128_PM4_STAT) & R128_PM4_FIFOCNT_MASK;
+ if (pScrn->CCEFifoSlots >= entries) return;
+ }
+ R128_DEBUG(("Reseting Engine: PM4_STAT = 0x%08x\n",
+ (unsigned int)INREG(R128_PM4_STAT)));
+ r128EngineReset(pScrn);
+ }
+}
+
+/* Wait until the CCE is completely idle: the FIFO has drained and the
+ CCE is idle. */
+void r128CCEWaitForIdle(r128ScreenPtr pScrn)
+{
+#if USE_IOCTLS
+ if (drmR128WaitForIdle(pScrn->driScreen->fd) < 0) {
+ fprintf(stderr, "Error: Rage 128 timed out... exiting\n");
+ exit(-1);
+ }
+#else
+ unsigned char *R128MMIO = pScrn->mmio;
+ int i;
+
+ if (R128CCE_USE_RING_BUFFER(pScrn->CCEMode)) {
+ OUTREGP(R128_PM4_BUFFER_DL_WPTR,
+ R128_PM4_BUFFER_DL_DONE, ~R128_PM4_BUFFER_DL_DONE);
+
+ for (;;) {
+ for (i = 0; i < R128_TIMEOUT; i++) {
+ if (*pScrn->ringReadPtr == pScrn->SAREA->ringWrite) {
+ int pm4stat = INREG(R128_PM4_STAT);
+ if ((pm4stat & R128_PM4_FIFOCNT_MASK) == pScrn->CCEFifoSize
+ && !(pm4stat & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE)))
+ return;
+ }
+ }
+ R128_DEBUG(("Reseting Engine: PM4_STAT = 0x%08x\n",
+ (unsigned int)INREG(R128_PM4_STAT)));
+ r128EngineReset(pScrn);
+ }
+ } else {
+ r128CCEWaitForFifoFunction(pScrn, pScrn->CCEFifoSize);
+
+ for (;;) {
+ for (i = 0; i < R128_TIMEOUT; i++) {
+ if (!(INREG(R128_PM4_STAT)
+ & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) {
+ r128EngineFlush(pScrn);
+ return;
+ }
+ }
+ R128_DEBUG(("Reseting Engine: PM4_STAT = 0x%08x\n",
+ (unsigned int)INREG(R128_PM4_STAT)));
+ r128EngineReset(pScrn);
+ }
+ }
+#endif
+}
+
+/* Send a packet to the CCE via the PIO registers */
+static void r128CCESubmitPacketPIO(r128ContextPtr r128ctx,
+ CARD32 *buf, int count)
+{
+ unsigned char *R128MMIO = r128ctx->r128Screen->mmio;
+#if DO_SECURITY_CHECK
+ CARD32 tmp = 0;
+ int psize = 0;
+ int writing = 1;
+ int addr = R128_PM4_FIFO_DATA_EVEN;
+#endif
+
+#if DO_SECURITY_CHECK
+ while (count > 0) {
+ tmp = *buf++;
+ if (!psize) {
+ writing = 1;
+
+ if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET0) {
+ if ((tmp & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2)) {
+ if ((tmp & R128_CCE_PACKET0_REG_MASK) !=
+ (R128_PM4_VC_FPU_SETUP >> 2)) {
+ writing = 0;
+ }
+ }
+ psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
+ } else if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET1) {
+ if ((tmp & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2)) {
+ if ((tmp & R128_CCE_PACKET1_REG0_MASK) !=
+ (R128_PM4_VC_FPU_SETUP >> 2)) {
+ writing = 0;
+ }
+ } else if ((tmp & R128_CCE_PACKET1_REG1_MASK) <=
+ (0x1004 << 9)) {
+ if ((tmp & R128_CCE_PACKET1_REG1_MASK) !=
+ (R128_PM4_VC_FPU_SETUP << 9)) {
+ writing = 0;
+ }
+ }
+ psize = 3;
+ } else {
+ psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
+ }
+ }
+ psize--;
+
+ if (writing) {
+ r128CCEWaitForFifo(r128ctx->r128Screen, 1);
+ OUTREG(addr, tmp);
+ addr ^= 0x0004;
+ }
+
+ count--;
+ }
+
+ if (addr == R128_PM4_FIFO_DATA_ODD) {
+ r128CCEWaitForFifo(r128ctx->r128Screen, 1);
+ OUTREG(addr, R128_CCE_PACKET2);
+ }
+#else
+ while (count > 1) {
+ r128CCEWaitForFifo(r128ctx->r128Screen, 2);
+ OUTREG(R128_PM4_FIFO_DATA_EVEN, *buf++);
+ OUTREG(R128_PM4_FIFO_DATA_ODD, *buf++);
+ count -= 2;
+ }
+
+ if (count) {
+ r128CCEWaitForFifo(r128ctx->r128Screen, 2);
+ OUTREG(R128_PM4_FIFO_DATA_EVEN, *buf);
+ OUTREG(R128_PM4_FIFO_DATA_ODD, R128_CCE_PACKET2);
+ }
+#endif
+}
+
+/* Send a packet to the CCE via the ring */
+static void r128CCESubmitPacketRing(r128ContextPtr r128ctx,
+ CARD32 *buf, int count)
+{
+ r128ScreenPtr r128scrn = r128ctx->r128Screen;
+ unsigned char *R128MMIO = r128ctx->r128Screen->mmio;
+ int ringWrite = r128scrn->SAREA->ringWrite;
+ int *ringWritePtr = r128scrn->ringStartPtr + ringWrite;
+ int timeout;
+#if DO_SECURITY_CHECK
+ CARD32 tmp = 0;
+ int psize = 0;
+ int writing = 1;
+#endif
+
+ if (count > r128scrn->ringEntries) {
+ /* FIXME */
+ return;
+ }
+
+ while (count > 0) {
+#if DO_SECURITY_CHECK
+ tmp = *buf++;
+ if (!psize) {
+ writing = 1;
+
+ if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET0) {
+ if ((tmp & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2)) {
+ if ((tmp & R128_CCE_PACKET0_REG_MASK) !=
+ (R128_PM4_VC_FPU_SETUP >> 2)) {
+ writing = 0;
+ }
+ }
+ psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
+ } else if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET1) {
+ if ((tmp & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2)) {
+ if ((tmp & R128_CCE_PACKET1_REG0_MASK) !=
+ (R128_PM4_VC_FPU_SETUP >> 2)) {
+ writing = 0;
+ }
+ } else if ((tmp & R128_CCE_PACKET1_REG1_MASK) <=
+ (0x1004 << 9)) {
+ if ((tmp & R128_CCE_PACKET1_REG1_MASK) !=
+ (R128_PM4_VC_FPU_SETUP << 9)) {
+ writing = 0;
+ }
+ }
+ psize = 3;
+ } else {
+ psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
+ }
+ }
+ psize--;
+
+ if (writing) {
+ ringWrite++;
+ *ringWritePtr++ = tmp;
+ }
+#else
+ ringWrite++;
+ *ringWritePtr++ = *buf++;
+#endif
+ if (ringWrite >= r128scrn->ringEntries) {
+ ringWrite = 0;
+ ringWritePtr = r128scrn->ringStartPtr;
+ }
+ timeout = 0;
+ while (ringWrite == *r128scrn->ringReadPtr) {
+ (void)INREG(R128_PM4_BUFFER_DL_RPTR);
+ if (timeout++ >= R128_TIMEOUT) r128EngineReset(r128scrn);
+ }
+
+ count--;
+ }
+
+ if (ringWrite < 32) {
+ memcpy(r128scrn->ringEndPtr,
+ r128scrn->ringStartPtr,
+ ringWrite * sizeof(int));
+ }
+
+ r128scrn->SAREA->ringWrite = ringWrite;
+ OUTREG(R128_PM4_BUFFER_DL_WPTR, ringWrite);
+}
+
+void r128CCESubmitPackets(r128ContextPtr r128ctx, CARD32 *buf, int count)
+{
+#if USE_IOCTLS
+ if (drmR128SubmitPackets(r128ctx->r128Screen->driScreen->fd,
+ r128ctx->CCEbuf, r128ctx->CCEcount,
+ 0) < 0) {
+ r128EngineReset(r128ctx->r128Screen);
+ fprintf(stderr, "Error: Illegal CCE packet... exiting\n");
+ exit(-1);
+ }
+#else
+ if (R128CCE_USE_RING_BUFFER(r128ctx->r128Screen->CCEMode))
+ r128CCESubmitPacketRing(r128ctx, buf, count);
+ else
+ r128CCESubmitPacketPIO(r128ctx, buf, count);
+#endif
+}
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_cce.h b/xc/lib/GL/mesa/src/drv/r128/r128_cce.h
new file mode 100644
index 000000000..162686cb7
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_cce.h
@@ -0,0 +1,142 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_CCE_H_
+#define _R128_CCE_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "r128_dri.h"
+#include "r128_reg.h"
+
+#include "xf86drmR128.h"
+
+typedef union {
+ float f;
+ int i;
+} floatTOint;
+
+#define R128_DEFAULT_TOTAL_CCE_TIMEOUT 1000000 /* usecs */
+
+/* Insert an integer value into the CCE ring buffer. */
+#define R128CCE(v) \
+ do { \
+ r128ctx->CCEbuf[r128ctx->CCEcount] = (v); \
+ r128ctx->CCEcount++; \
+ } while (0)
+
+/* Insert an floating point value into the CCE ring buffer. */
+#define R128CCEF(v) \
+ do { \
+ floatTOint fTi; \
+ fTi.f = (v); \
+ r128ctx->CCEbuf[r128ctx->CCEcount] = fTi.i; \
+ r128ctx->CCEcount++; \
+ } while (0)
+
+#if USE_USER_SPACE_RING
+
+#define R128CCE_SUBMIT_PACKETS() \
+ do { \
+ r128CCESubmitPackets(r128ctx, r128ctx->CCEbuf, r128ctx->CCEcount); \
+ r128ctx->CCEcount = 0; \
+ } while (0)
+
+#define R128CCE_WAIT_FOR_IDLE(r128ctx) \
+ r128CCEWaitForIdle(r128ctx->r128Screen)
+
+#else /* if !USE_USER_SPACE_RING */
+
+#define R128CCE_SUBMIT_PACKETS() \
+ do { \
+ CARD32 *_buf; \
+ int _c = r128ctx->CCEcount; \
+ int _fd = r128ctx->r128Screen->driScreen->fd; \
+ int _to = 0; \
+ int _ret; \
+ \
+ do { \
+ _buf = r128ctx->CCEbuf + (r128ctx->CCEcount - _c); \
+ _ret = drmR128SubmitPackets(_fd, _buf, &_c, 0); \
+ } while (_ret < 0 && _ret == -EBUSY && _to++ < r128ctx->CCEtimeout); \
+ if (_ret < 0) { \
+ (void)drmR128EngineReset(_fd); \
+ fprintf(stderr, "Error: Could not submit packet... exiting\n"); \
+ exit(-1); \
+ } \
+ r128ctx->CCEcount = 0; \
+ } while (0)
+
+#define R128CCE_WAIT_FOR_IDLE(r128ctx) \
+ do { \
+ int _fd = r128ctx->r128Screen->driScreen->fd; \
+ int _to = 0; \
+ int _ret; \
+ \
+ (void)drmR128EngineFlush(_fd); \
+ do { \
+ _ret = drmR128CCEWaitForIdle(_fd); \
+ } while (_ret < 0 && _ret == -EBUSY && _to++ < r128ctx->CCEtimeout); \
+ if (_ret < 0) { \
+ (void)drmR128EngineReset(_fd); \
+ fprintf(stderr, "Error: Rage 128 timed out... exiting\n"); \
+ exit(-1); \
+ } \
+ } while (0)
+
+#endif
+
+#define R128CCE_WAIT_FOR_IDLE_LOCK(r128ctx) \
+ do { \
+ LOCK_HARDWARE(r128ctx); \
+ R128CCE_WAIT_FOR_IDLE(r128ctx); \
+ UNLOCK_HARDWARE(r128ctx); \
+ } while (0)
+
+
+/* Insert a type-[0123] packet header into the ring buffer */
+#define R128CCE0(p,r,n) R128CCE((p) | ((n) << 16) | ((r) >> 2))
+#define R128CCE1(p,r1,r2) R128CCE((p) | (((r2) >> 2) << 11) | ((r1) >> 2))
+#define R128CCE2(p) R128CCE((p))
+#define R128CCE3(p,n) R128CCE((p) | ((n) << 16))
+
+
+#if USE_USER_SPACE_RING
+extern void r128CCEWaitForIdle(r128ScreenPtr pScrn);
+extern void r128CCESubmitPackets(r128ContextPtr r128ctx,
+ CARD32 *buf, int count);
+#endif
+
+#endif
+#endif /* _R128_CCE_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_ccevb.h b/xc/lib/GL/mesa/src/drv/r128/r128_ccevb.h
new file mode 100644
index 000000000..2084b8672
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_ccevb.h
@@ -0,0 +1,224 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_CCEVB_H_
+#define _R128_CCEVB_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "xf86drmR128.h"
+
+typedef struct {
+ CARD32 *buf; /* Pointer to current VB */
+ int index; /* Index of current VB */
+ int start; /* in bytes from the beginning of the VB map */
+ int size; /* in vertices */
+ int count; /* in vertices */
+ drmR128PrimType prim; /* Primitive type for vertices in VB */
+ int done; /* VB has been sent to ring */
+} r128CCEVertBuf, *r128CCEVertBufPtr;
+
+
+
+/* Flush the CPU's write-combining cache */
+/* FIXME: This code is both processor and compiler specific */
+#define R128_FLUSH_WC_MEMORY() \
+ do { \
+ int xchangeDummy; \
+ \
+ __asm__ volatile("push %%eax ;" \
+ "xchg %%eax, %0 ;" \
+ "pop %%eax" : : "m" (xchangeDummy)); \
+ __asm__ volatile("push %%eax ;" \
+ "push %%ebx ;" \
+ "push %%ecx ;" \
+ "push %%edx ;" \
+ "movl $0,%%eax ;" \
+ "cpuid ;" \
+ "pop %%edx ;" \
+ "pop %%ecx ;" \
+ "pop %%ebx ;" \
+ "pop %%eax" : /* no outputs */ : /* no inputs */); \
+ } while (0)
+
+
+/* Get a new VB from the pool of vertex buffers in AGP space */
+/* NOTE: By default the primitive type for a VB is set to individual tris */
+#define R128CCE_GET_NEW_VB(r128ctx) \
+ do { \
+ r128CCEVertBufPtr vb = &r128ctx->vb; \
+ int to = 0; \
+ int fd = r128ctx->r128Screen->driScreen->fd; \
+ int num; \
+ int index; \
+ int size; \
+ \
+ vb->buf = NULL; \
+ \
+ LOCK_HARDWARE(r128ctx); \
+ while (!vb->buf && to++ < r128ctx->CCEtimeout) { \
+ /* Ask the kernel a new vertex buffer */ \
+ num = drmR128GetVertexBuffers(fd, 1, &index, &size); \
+ \
+ if (num > 0) { \
+ vb->buf = (CARD32 *)(r128ctx->r128Screen-> \
+ vbBufs->list[index].address); \
+ vb->index = index; \
+ vb->start = index*r128ctx->r128Screen->vbBufSize; \
+ vb->size = size/sizeof(r128_vertex); \
+ vb->count = 0; \
+ vb->prim = DRM_R128_PRIM_TRI_LIST; \
+ vb->done = GL_FALSE; \
+ } \
+ } \
+ UNLOCK_HARDWARE(r128ctx); \
+ \
+ if (!vb->buf) { \
+ (void)drmR128EngineReset(fd); \
+ fprintf(stderr, "Error: Could not get new VB... exiting\n"); \
+ exit(-1); \
+ } \
+ } while (0)
+
+/* Submit a VB to the hardware for processing */
+/* NOTE: This macro is only called while holding the hardware lock */
+#define R128CCE_SUBMIT_VB(r128ctx) \
+ do { \
+ int index = r128ctx->vb.index; \
+ int size = r128ctx->vb.count; \
+ int fd = r128ctx->r128Screen->driScreen->fd; \
+ int to = 0; \
+ int ret; \
+ CARD32 prim; \
+ \
+ switch (r128ctx->vb.prim) { \
+ case DRM_R128_PRIM_NONE: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_NONE; \
+ break; \
+ case DRM_R128_PRIM_POINT: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_POINT; \
+ break; \
+ case DRM_R128_PRIM_LINE: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_LINE; \
+ break; \
+ case DRM_R128_PRIM_POLY_LINE: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_POLY_LINE; \
+ break; \
+ case DRM_R128_PRIM_TRI_LIST: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST; \
+ break; \
+ case DRM_R128_PRIM_TRI_FAN: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN; \
+ break; \
+ case DRM_R128_PRIM_TRI_STRIP: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_STRIP; \
+ break; \
+ case DRM_R128_PRIM_TRI_TYPE2: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2; \
+ break; \
+ default: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_NONE; \
+ break; \
+ } \
+ \
+ /* Send the vertex buffer to the hardware */ \
+ BEGIN_CLIP_LOOP(r128ctx); \
+ \
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_INDX_PRIM, 3); \
+ R128CCE(r128ctx->r128Screen->vbOffset + r128ctx->vb.start); \
+ R128CCE(r128ctx->vb.count); \
+ R128CCE(R128_FULL_VERTEX_FORMAT); \
+ R128CCE(prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST | \
+ (r128ctx->vb.count << R128_CCE_VC_CNTL_NUM_SHIFT)); \
+ R128CCE_SUBMIT_PACKETS(); \
+ \
+ END_CLIP_LOOP(r128ctx); \
+ \
+ /* Tell the kernel to release the vertex buffer */ \
+ do { \
+ ret = drmR128FlushVertexBuffers(fd, 1, &index, &size, \
+ r128ctx->vb.prim); \
+ } while (ret < 0 && ret == -EBUSY && to++ < r128ctx->CCEtimeout); \
+ if (ret < 0) { \
+ (void)drmR128EngineReset(fd); \
+ fprintf(stderr, "Error: Could not flush VB... exiting\n"); \
+ exit(-1); \
+ } \
+ \
+ r128ctx->vb.done = GL_TRUE; \
+ } while (0)
+
+/* Flush the vertex buffer (assuming we already hold the lock) */
+#define R128CCE_FLUSH_VB(r128ctx) \
+ do { \
+ if (r128ctx->vb.count && !r128ctx->vb.done) { \
+ /* FIXME: Is this _really_ needed? */ \
+ if (!R128CCE_USE_RING_BUFFER(r128ctx->r128Screen->CCEMode)) \
+ R128CCE_WAIT_FOR_IDLE(r128ctx); \
+ \
+ R128CCE_SUBMIT_VB(r128ctx); \
+ } \
+ } while (0)
+
+/* Flush the vertex buffer */
+#define R128CCE_FLUSH_VB_LOCK(r128ctx) \
+ do { \
+ LOCK_HARDWARE(r128ctx); \
+ R128CCE_FLUSH_VB(r128ctx); \
+ UNLOCK_HARDWARE(r128ctx); \
+ } while (0)
+
+/* Reserve space in a VB to store `n' vertices, and set the pointer `p'
+ to point to the next vertex in the current VB. If adding these
+ vertices to the VB would exceed the size of the VB, then flush the
+ current VB, get a new one from the pool of VBs, reserve space in the
+ new VB for the `n' vertices, and set the pointer `p' to point to the
+ first vertex in the new VB. */
+#define R128CCE_ALLOC_VB_SPACE(r128ctx, p, n) \
+ do { \
+ r128CCEVertBufPtr vb = &r128ctx->vb; \
+ \
+ if (vb->done) R128CCE_GET_NEW_VB(r128ctx); \
+ \
+ if (vb->count + (n) > vb->size) { \
+ R128CCE_FLUSH_VB_LOCK(r128ctx); \
+ R128CCE_GET_NEW_VB(r128ctx); \
+ } \
+ \
+ (p) = (r128_vertex *)vb->buf + vb->count; \
+ vb->count += (n); \
+ } while (0)
+
+#endif
+#endif /* _R128_CCEVB_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_clear.c b/xc/lib/GL/mesa/src/drv/r128/r128_clear.c
new file mode 100644
index 000000000..9ab0581b0
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_clear.c
@@ -0,0 +1,248 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+#include "r128_state.h"
+#include "r128_vb.h"
+#include "r128_clear.h"
+
+/* Clear the depth buffer */
+void r128ClearDepthBuffer(r128ContextPtr r128ctx, GLboolean all,
+ GLint cx, GLint cy, GLint cw, GLint ch)
+{
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable;
+ int nc;
+ XF86DRIClipRectPtr c;
+ int dst_bpp;
+ CARD32 write_mask;
+
+ if (!(r128ctx->regs.tex_cntl_c & R128_Z_WRITE_ENABLE)) return;
+
+ switch (r128ctx->regs.z_sten_cntl_c & R128_Z_PIX_WIDTH_MASK) {
+ case R128_Z_PIX_WIDTH_16:
+ write_mask = 0x0000ffff;
+ dst_bpp = R128_GMC_DST_16BPP;
+ break;
+ case R128_Z_PIX_WIDTH_24:
+ write_mask = 0x00ffffff;
+ dst_bpp = R128_GMC_DST_32BPP;
+ break;
+ case R128_Z_PIX_WIDTH_32:
+ write_mask = 0xffffffff;
+ dst_bpp = R128_GMC_DST_32BPP;
+ break;
+ default: return;
+ }
+
+ cx += dPriv->x;
+ cy = dPriv->y + dPriv->h - cy - ch;
+
+ LOCK_HARDWARE(r128ctx);
+
+ /* Flush any outstanding vertex buffers */
+ R128CCE_FLUSH_VB(r128ctx);
+
+ /* Init the clip rects here in case they changed during the
+ LOCK_HARDWARE macro */
+ c = dPriv->pClipRects;
+ nc = dPriv->numClipRects;
+
+ /* Set the write mask so that we _only_ clear the Z buffer */
+ R128CCE0(R128_CCE_PACKET0, R128_DP_WRITE_MASK, 0);
+ R128CCE(write_mask);
+
+ /* Temporarily disable Z and stencil buffer and texture mapping modes */
+ R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0);
+ R128CCE(r128ctx->regs.tex_cntl_c & ~(R128_Z_ENABLE |
+ R128_STENCIL_ENABLE |
+ R128_TEXMAP_ENABLE));
+
+ /* Cycle through the clip rects */
+ while (nc--) {
+ int x = c[nc].x1;
+ int y = c[nc].y1;
+ int w = c[nc].x2 - x;
+ int h = c[nc].y2 - y;
+
+ if (!all) {
+ if (x < cx) w -= cx - x, x = cx;
+ if (y < cy) h -= cy - y, y = cy;
+
+ if (x + w > cx + cw) w = cx + cw - x;
+ if (y + h > cy + ch) h = cy + ch - y;
+
+ if (w <= 0 || h <= 0) continue;
+ }
+
+ x += r128ctx->r128Screen->depthX;
+ y += r128ctx->r128Screen->depthY;
+
+ R128CCE3(R128_CCE_PACKET3_CNTL_PAINT_MULTI, 3);
+ R128CCE(R128_GMC_BRUSH_SOLID_COLOR
+ | dst_bpp
+ | R128_GMC_SRC_DATATYPE_COLOR
+ | R128_ROP3_P
+ | R128_GMC_3D_FCN_EN /* FIXME?? */
+ | R128_GMC_CLR_CMP_CNTL_DIS /* FIXME?? */
+ | R128_AUX_CLIP_DIS /* FIXME?? */
+ | R128_GMC_WR_MSK_DIS); /* FIXME?? */
+ R128CCE(r128ctx->ClearDepth);
+ R128CCE((x << 16) | y);
+ R128CCE((w << 16) | h);
+ }
+
+#if 0
+ /* Set the write mask so that we _only_ clear the Z buffer */
+ R128CCE0(R128_CCE_PACKET0, R128_DP_WRITE_MASK, 0);
+ R128CCE(0xffffffff);
+
+ /* Restore Z and stencil buffer and texture mapping modes */
+ R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0);
+ R128CCE(r128ctx->regs.tex_cntl_c);
+#else
+ /* FIXME: We should be able to optimize this by restoring only the
+ registers that change (above) */
+ /* NOTE: The restore of TEX_CNTL_C and R128_DP_WRITE_MASK is handled by
+ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ALL_DIRTY;
+#endif
+
+ R128CCE_SUBMIT_PACKETS();
+
+ UNLOCK_HARDWARE(r128ctx);
+}
+
+/* Clear a color buffer */
+void r128ClearColorBuffer(r128ContextPtr r128ctx, GLboolean all,
+ GLint cx, GLint cy, GLint cw, GLint ch,
+ GLint drawX, GLint drawY)
+{
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable;
+ int nc;
+ XF86DRIClipRectPtr c;
+ int dst_bpp;
+
+ switch (r128ctx->r128Screen->bpp) {
+ case 8:
+ dst_bpp = R128_GMC_DST_8BPP_CI;
+ break;
+ case 16:
+ if (r128ctx->r128Screen->depth == 15) dst_bpp = R128_GMC_DST_15BPP;
+ else dst_bpp = R128_GMC_DST_16BPP;
+ break;
+ case 24:
+ dst_bpp = R128_GMC_DST_24BPP;
+ break;
+ case 32:
+ default:
+ dst_bpp = R128_GMC_DST_32BPP;
+ break;
+ }
+
+ cx += dPriv->x;
+ cy = dPriv->y + dPriv->h - cy - ch;
+
+ LOCK_HARDWARE(r128ctx);
+
+ /* Flush any outstanding vertex buffers */
+ R128CCE_FLUSH_VB(r128ctx);
+
+ /* Init the clip rects here in case they changed during the
+ LOCK_HARDWARE macro */
+ c = dPriv->pClipRects;
+ nc = dPriv->numClipRects;
+
+ /* Temporarily disable Z and stencil buffer and texture mapping modes */
+ R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0);
+ R128CCE(r128ctx->regs.tex_cntl_c & ~(R128_Z_ENABLE |
+ R128_STENCIL_ENABLE |
+ R128_TEXMAP_ENABLE));
+
+ /* Cycle through the clip rects */
+ while (nc--) {
+ int x = c[nc].x1;
+ int y = c[nc].y1;
+ int w = c[nc].x2 - x;
+ int h = c[nc].y2 - y;
+
+ if (!all) {
+ if (x < cx) w -= cx - x, x = cx;
+ if (y < cy) h -= cy - y, y = cy;
+
+ if (x + w > cx + cw) w = cx + cw - x;
+ if (y + h > cy + ch) h = cy + ch - h;
+
+ if (w <= 0 || h <= 0) continue;
+ }
+
+ x += drawX;
+ y += drawY;
+
+ R128CCE3(R128_CCE_PACKET3_CNTL_PAINT_MULTI, 3);
+ R128CCE(R128_GMC_BRUSH_SOLID_COLOR
+ | dst_bpp
+ | R128_GMC_SRC_DATATYPE_COLOR
+ | R128_ROP3_P
+ | R128_GMC_3D_FCN_EN /* FIXME?? */
+ | R128_GMC_CLR_CMP_CNTL_DIS /* FIXME?? */
+ | R128_AUX_CLIP_DIS); /* FIXME?? */
+ R128CCE(r128ctx->ClearColor);
+ R128CCE((x << 16) | y);
+ R128CCE((w << 16) | h);
+ }
+
+#if 0
+ /* Restore Z and stencil buffer and texture mapping modes */
+ R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0);
+ R128CCE(r128ctx->regs.tex_cntl_c);
+#else
+ /* FIXME: We should be able to optimize this by restoring only the
+ registers that change (above) */
+ /* NOTE: The restore of TEX_CNTL_C is handled by
+ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ALL_DIRTY;
+#endif
+
+ R128CCE_SUBMIT_PACKETS();
+
+ UNLOCK_HARDWARE(r128ctx);
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_clear.h b/xc/lib/GL/mesa/src/drv/r128/r128_clear.h
new file mode 100644
index 000000000..7018b05b4
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_clear.h
@@ -0,0 +1,47 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_CLEAR_H_
+#define _R128_CLEAR_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void r128ClearDepthBuffer(r128ContextPtr r128ctx, GLboolean all,
+ GLint x, GLint y, GLint width, GLint height);
+extern void r128ClearColorBuffer(r128ContextPtr r128ctx, GLboolean all,
+ GLint x, GLint y, GLint width, GLint height,
+ GLint drawX, GLint drawY);
+
+#endif
+#endif /* _R128_CLEAR_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.c b/xc/lib/GL/mesa/src/drv/r128/r128_context.c
new file mode 100644
index 000000000..01573f559
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.c
@@ -0,0 +1,203 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include <stdlib.h>
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_cce.h"
+#include "r128_dd.h"
+#include "r128_state.h"
+#include "r128_span.h"
+#include "r128_tex.h"
+#include "r128_vb.h"
+#include "r128_pipeline.h"
+
+#include "context.h"
+#include "simple_list.h"
+
+/* Create the device specific context */
+GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual,
+ __DRIcontextPrivate *driContextPriv)
+{
+ r128ContextPtr r128ctx;
+ r128ScreenPtr r128scrn;
+ GLcontext *glCtx = driContextPriv->mesaContext;
+ int i;
+ char *v;
+
+ r128ctx = (r128ContextPtr)Xmalloc(sizeof(*r128ctx));
+ if (!r128ctx) return GL_FALSE;
+
+ /* Initialize r128Context */
+ r128ctx->glCtx = glCtx;
+ r128ctx->display = dpy;
+ r128ctx->driContext = driContextPriv;
+ r128ctx->driDrawable = NULL; /* Set by XMesaMakeCurrent */
+
+ if (getenv("LIBGL_SOFTWARE_RENDERING"))
+ r128ctx->SWonly = GL_TRUE;
+ else
+ r128ctx->SWonly = GL_FALSE;
+ if (getenv("LIBGL_NO_SOFTWARE_FALLBACKS"))
+ r128ctx->SWfallbackDisable = GL_TRUE;
+ else
+ r128ctx->SWfallbackDisable = GL_FALSE;
+ r128scrn = r128ctx->r128Screen =
+ (r128ScreenPtr)(driContextPriv->driScreenPriv->private);
+
+ r128ctx->CurrentTexObj[0] = NULL;
+ r128ctx->CurrentTexObj[1] = NULL;
+ make_empty_list(&r128ctx->SwappedOut);
+ for (i = 0; i < r128scrn->NRTexHeaps; i++) {
+ make_empty_list(&r128ctx->TexObjList[i]);
+ r128ctx->texHeap[i] = mmInit(0, r128scrn->texSize[i]);
+ r128ctx->lastTexAge[i] = -1;
+ }
+
+ r128ctx->lastSwapAge = 0;
+
+ r128ctx->useFastPath = GL_FALSE;
+
+ r128ctx->vb.start = 0;
+ r128ctx->vb.count = 0;
+ r128ctx->vb.size = 0;
+ r128ctx->vb.index = 0;
+ r128ctx->vb.buf = NULL;
+ r128ctx->vb.done = GL_TRUE;
+
+ if (r128scrn->IsPCI || getenv("LIBGL_DISABLE_VERTEX_BUFFERS"))
+ r128ctx->disableVB = GL_TRUE;
+ else
+ r128ctx->disableVB = GL_FALSE;
+
+ r128ctx->CCEbuf = (CARD32 *)malloc(sizeof(*r128ctx->CCEbuf) *
+ r128scrn->ringEntries);
+ r128ctx->CCEcount = 0;
+
+ if ((v = getenv("LIBGL_CCE_TIMEOUT")))
+ r128ctx->CCEtimeout = strtoul(v, NULL, 10);
+ else
+ r128ctx->CCEtimeout = (R128_DEFAULT_TOTAL_CCE_TIMEOUT /
+ R128_DEFAULT_CCE_TIMEOUT);
+ if (r128ctx->CCEtimeout <= 0) r128ctx->CCEtimeout = 1;
+
+ /* Initialize GLcontext */
+ glCtx->DriverCtx = (void *)r128ctx;
+
+ r128DDInitExtensions(glCtx);
+
+ r128DDInitDriverFuncs(glCtx);
+ r128DDInitStateFuncs(glCtx);
+ r128DDInitSpanFuncs(glCtx);
+ r128DDInitTextureFuncs(glCtx);
+
+ glCtx->Driver.TriangleCaps = (DD_TRI_CULL
+ | DD_TRI_LIGHT_TWOSIDE
+ | DD_TRI_OFFSET);
+#if 0
+ /* FIXME */
+ glCtx->TriangleCaps |= DD_CLIP_FOG_COORD;
+#endif
+
+ /* Reset Mesa's current 2D texture pointers to the driver's textures */
+ glCtx->Shared->DefaultD[2][0].DriverData = NULL;
+ glCtx->Shared->DefaultD[2][1].DriverData = NULL;
+
+ /* If Mesa has current a vertex buffer, make sure the driver's VB
+ data is up to date */
+ if (glCtx->VB) r128DDRegisterVB(glCtx->VB);
+
+ /* Register the fast path */
+ if (glCtx->NrPipelineStages)
+ glCtx->NrPipelineStages =
+ r128RegisterPipelineStages(glCtx->PipelineStage,
+ glCtx->PipelineStage,
+ glCtx->NrPipelineStages);
+
+ r128DDInitState(r128ctx);
+
+ driContextPriv->driverPrivate = (void *)r128ctx;
+
+ return GL_TRUE;
+}
+
+/* Destroy the device specific context */
+void r128DestroyContext(r128ContextPtr r128ctx)
+{
+ if (r128ctx) {
+ r128TexObjPtr t, next_t;
+ int i;
+
+ free(r128ctx->CCEbuf);
+
+ for (i = 0; i < r128ctx->r128Screen->NRTexHeaps; i++) {
+ foreach_s (t, next_t, &r128ctx->TexObjList[i])
+ r128DestroyTexObj(r128ctx, t);
+ }
+
+ foreach_s (t, next_t, &r128ctx->SwappedOut)
+ r128DestroyTexObj(r128ctx, t);
+
+ gl_destroy_context(r128ctx->glCtx);
+ Xfree(r128ctx);
+ }
+}
+
+/* Load the device specific context into the hardware. The actual
+ setting of the hardware state is done in the r128UpdateHWState(). */
+r128ContextPtr r128MakeCurrent(r128ContextPtr oldCtx,
+ r128ContextPtr newCtx,
+ __DRIdrawablePrivate *dPriv)
+{
+ if (oldCtx) {
+ if (!R128CCE_USE_RING_BUFFER(newCtx->r128Screen->CCEMode))
+ newCtx->dirty |= R128_REQUIRE_QUIESCENCE;
+ if (oldCtx != newCtx) {
+ newCtx->dirty |= R128_UPDATE_CONTEXT;
+ newCtx->dirty_context |= R128_CTX_ALL_DIRTY;
+ }
+ if (oldCtx->driDrawable != dPriv)
+ newCtx->dirty |= R128_UPDATE_WINPOS;
+ } else {
+ newCtx->dirty |= R128_UPDATE_CONTEXT;
+ newCtx->dirty_context |= R128_CTX_ALL_DIRTY;
+ }
+
+ newCtx->driDrawable = dPriv;
+
+ return newCtx;
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.h b/xc/lib/GL/mesa/src/drv/r128/r128_context.h
new file mode 100644
index 000000000..189a22cbe
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.h
@@ -0,0 +1,219 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_CONTEXT_H_
+#define _R128_CONTEXT_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "r128_texobj.h"
+#include "r128_fastpath.h"
+#include "r128_ccevb.h"
+
+/* Flags for what needs to be updated before a new primitive is rendered */
+#define R128_CLEAN 0x0000
+#define R128_REQUIRE_QUIESCENCE 0x0001
+#define R128_UPDATE_CONTEXT 0x0002
+#define R128_UPDATE_WINPOS 0x0004
+#define R128_UPDATE_TEX0IMAGES 0x0008
+#define R128_UPDATE_TEX1IMAGES 0x0010
+#define R128_UPDATE_TEXSTATE 0x0020
+#define R128_ALL_DIRTY 0xffff
+
+/* Flags for what context state needs to be updated */
+#define R128_CTX_CLEAN 0x0000
+#define R128_CTX_MISC 0x0001
+#define R128_CTX_ENGINESTATE 0x0002
+#define R128_CTX_TEX0STATE 0x0004
+#define R128_CTX_TEX1STATE 0x0008
+#define R128_CTX_TEXENVSTATE 0x0010
+#define R128_CTX_FOGSTATE 0x0020
+#define R128_CTX_FOGTABLE 0x0040
+#define R128_CTX_ZSTENSTATE 0x0080
+#define R128_CTX_SCISSORS 0x0100
+#define R128_CTX_ALPHASTATE 0x0200
+#define R128_CTX_SETUPSTATE 0x0400
+#define R128_CTX_WIN_Z_POS 0x0800
+#define R128_CTX_FLUSH_PIX_CACHE 0x1000
+#define R128_CTX_ALL_DIRTY 0xffff
+
+/* Flags for software fallback cases */
+#define R128_FALLBACK_TEXTURE 0x0001
+#define R128_FALLBACK_DRAW_BUFFER 0x0002
+#define R128_FALLBACK_READ_BUFFER 0x0004
+#define R128_FALLBACK_COLORMASK 0x0008
+#define R128_FALLBACK_STIPPLE 0x0010
+
+/* NOTE: The groups below need to be kept together so that a single
+ memcpy can be used to transfer data to the ring buffer */
+typedef struct {
+ CARD32 scale_3d_cntl; /* 0x1a00 */
+
+ CARD32 aux_sc_cntl; /* 0x1660 */
+ CARD32 aux1_sc_left;
+ CARD32 aux1_sc_right;
+ CARD32 aux1_sc_top;
+ CARD32 aux1_sc_bottom;
+ CARD32 aux2_sc_left;
+ CARD32 aux2_sc_right;
+ CARD32 aux2_sc_top;
+ CARD32 aux2_sc_bottom;
+ CARD32 aux3_sc_left;
+ CARD32 aux3_sc_right;
+ CARD32 aux3_sc_top;
+ CARD32 aux3_sc_bottom; /* 0x1690 */
+
+ CARD32 dst_pitch_offset_c; /* 0x1c80 */
+ CARD32 dp_gui_master_cntl;
+ CARD32 sc_top_left_c;
+ CARD32 sc_bottom_right_c;
+ CARD32 z_offset_c;
+ CARD32 z_pitch_c;
+ CARD32 z_sten_cntl_c;
+ CARD32 tex_cntl_c;
+ CARD32 misc_3d_state_cntl_reg;
+ CARD32 texture_clr_cmp_clr_c;
+ CARD32 texture_clr_cmp_msk_c;
+ CARD32 fog_color_c;
+ CARD32 prim_tex_cntl_c;
+ CARD32 prim_texture_combine_cntl_c;
+ CARD32 tex_size_pitch_c;
+ CARD32 prim_tex_offset[R128_TEX_MAXLEVELS]; /* 0x1ce4 */
+
+ CARD32 sec_tex_cntl_c; /* 0x1d00 */
+ CARD32 sec_tex_combine_cntl_c;
+ CARD32 sec_tex_offset[R128_TEX_MAXLEVELS];
+ CARD32 constant_color_c;
+ CARD32 prim_texture_border_color_c;
+ CARD32 sec_texture_border_color_c;
+ CARD32 sten_ref_mask_c;
+ CARD32 plane_3d_mask_c; /* 0x1d44 */
+
+ CARD32 setup_cntl; /* 0x1bc4 */
+
+ CARD32 pm4_vc_fpu_setup; /* 0x071c */
+
+ CARD32 fog_3d_table_start; /* 0x1810 */
+ CARD32 fog_3d_table_end;
+ CARD32 fog_3d_table_density; /* 0x181c */
+
+ CARD32 window_xy_offset; /* 0x1bcc */
+
+ CARD32 dp_write_mask; /* 0x16cc */
+
+ CARD32 pc_gui_ctlstat; /* 0x1748 */
+} r128ContextRegs;
+
+typedef struct {
+ GLcontext *glCtx; /* Mesa context */
+ int dirty; /* Hardware state to be updated */
+ int dirty_context; /* Context state to be updated */
+
+ int SWonly; /* Force software-only rendering */
+ int SWfallbackDisable; /* Disable software fallbacks */
+
+ r128TexObjPtr CurrentTexObj[2]; /* Ptr to current texture
+ object associated with
+ each texture unit */
+ /* List of tex swapped in per heap*/
+ r128TexObj TexObjList[R128_NR_TEX_HEAPS];
+ r128TexObj SwappedOut; /* List of textures swapped out */
+ memHeap_t *texHeap[R128_NR_TEX_HEAPS]; /* Global tex heaps */
+ /* Last known global tex heap ages */
+ int lastTexAge[R128_NR_TEX_HEAPS];
+
+ CARD32 lastSwapAge; /* Last known swap age */
+
+ GLenum FogMode; /* Current fog equation */
+
+ int Scissor;
+ XF86DRIClipRectRec ScissorRect; /* Current software scissor */
+
+ int useFastPath; /* Currently using Fast Path code */
+ int SetupIndex; /* Raster setup function index */
+ int SetupDone; /* Partial raster setup done? */
+ int RenderIndex; /* Render state function index */
+ r128InterpFunc interp; /* Current vert interp function */
+
+ r128CCEVertBuf vb; /* VB currently being filled */
+ int disableVB; /* Disable the use of vertex buffers */
+
+ points_func PointsFunc; /* Current Points, Line, Triangle */
+ line_func LineFunc; /* and Quad rendering functions */
+ triangle_func TriangleFunc;
+ quad_func QuadFunc;
+
+ CARD32 IndirectTriangles; /* Flags for point, line,
+ tri and quad software
+ fallbacks */
+ CARD32 Fallback; /* Need software fallback */
+
+ r128ContextRegs regs; /* Hardware state */
+ CARD32 Color; /* Current draw color */
+ CARD32 ClearColor; /* Color used to clear color buffer */
+ CARD32 ClearDepth; /* Value used to clear depth buffer */
+
+ int drawX; /* x-offset to current draw buffer */
+ int drawY; /* y-offset to current draw buffer */
+
+ int readX; /* x-offset to current read buffer */
+ int readY; /* y-offset to current read buffer */
+
+ CARD32 *CCEbuf; /* buffer to submit to CCE */
+ int CCEcount; /* number of dwords in CCEbuf */
+
+ int CCEtimeout; /* number of times to loop
+ before exiting */
+
+ Display *display; /* X server display */
+
+ __DRIcontextPrivate *driContext; /* DRI context */
+ __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */
+
+ r128ScreenPtr r128Screen; /* Screen private DRI data */
+} r128ContextRec, *r128ContextPtr;
+
+#define R128_MESACTX(r128ctx) ((r128ctx)->glCtx)
+#define R128_DRIDRAWABLE(r128ctx) ((r128ctx)->driDrawable)
+#define R128_DRISCREEN(r128ctx) ((r128ctx)->r128Screen->driScreen)
+
+extern GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual,
+ __DRIcontextPrivate *driContextPriv);
+extern void r128DestroyContext(r128ContextPtr r128ctx);
+extern r128ContextPtr r128MakeCurrent(r128ContextPtr oldCtx,
+ r128ContextPtr newCtx,
+ __DRIdrawablePrivate *dPriv);
+
+#endif
+#endif /* _R128_CONTEXT_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c
new file mode 100644
index 000000000..0ed7ae471
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c
@@ -0,0 +1,182 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_cce.h"
+#include "r128_clear.h"
+#include "r128_state.h"
+#include "r128_vb.h"
+#include "r128_pipeline.h"
+#include "r128_dd.h"
+
+/* Driver entry point for clearing color and ancillary buffers */
+static GLbitfield r128DDClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint x, GLint y, GLint width, GLint height)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ if (r128ctx->SWonly) {
+ /* FIXME: Provide software fallback for this case?? */
+ }
+
+ if (mask & DD_FRONT_LEFT_BIT) {
+ r128ClearColorBuffer(r128ctx, all, x, y, width, height,
+ r128ctx->r128Screen->fbX,
+ r128ctx->r128Screen->fbY);
+ mask &= ~DD_FRONT_LEFT_BIT;
+ }
+
+ if (mask & DD_BACK_LEFT_BIT) {
+ r128ClearColorBuffer(r128ctx, all, x, y, width, height,
+ r128ctx->r128Screen->backX,
+ r128ctx->r128Screen->backY);
+ mask &= ~DD_BACK_LEFT_BIT;
+ }
+
+ if (mask & DD_DEPTH_BIT) {
+ r128ClearDepthBuffer(r128ctx, all, x, y, width, height);
+ mask &= ~DD_DEPTH_BIT;
+ }
+
+#if 0
+ /* FIXME: Add stencil support */
+ if (mask & DD_STENCIL_BIT) {
+ r128ClearStencilBuffer(r128ctx, all, x, y, width, height);
+ mask &= ~DD_STENCIL_BIT;
+ }
+#endif
+
+ return mask;
+}
+
+/* Return the current color buffer size */
+static void r128DDGetBufferSize(GLcontext *ctx, GLuint *width, GLuint *height)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ *width = r128ctx->driDrawable->w;
+ *height = r128ctx->driDrawable->h;
+}
+
+/* Return various strings for glGetString() */
+static const GLubyte *r128DDGetString(GLcontext *ctx, GLenum name)
+{
+ switch (name) {
+ case GL_VENDOR:
+ return (GLubyte *)"Precision Insight, Inc.";
+ case GL_RENDERER:
+ return (GLubyte *)"Mesa DRI Rage128 20000320";
+ default:
+ return NULL;
+ }
+}
+
+/* Send all commands to the hardware. If vertex buffers or indirect
+ buffers are in use, then we need to make sure they are sent to the
+ hardware. All commands that are normally sent to the ring are
+ already considered `flushed'. */
+static void r128DDFlush(GLcontext *ctx)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+}
+
+/* Make sure all commands have been sent to the hardware and have
+ completed processing. */
+static void r128DDFinish(GLcontext *ctx)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ r128DDFlush(ctx);
+ R128CCE_WAIT_FOR_IDLE_LOCK(r128ctx);
+}
+
+/* Return various parameters requested by Mesa */
+static GLint r128DDGetParameteri(const GLcontext *ctx, GLint param)
+{
+ switch (param) {
+#if 0
+ /* FIXME: Support for these needs to be added to Mesa */
+ case DD_MAX_TEXTURE_SIZE: return 1024;
+ case DD_MAX_TEXTURES: return 2;
+#endif
+#if 0
+ case DD_HAVE_HARDWARE_FOG: return 1; /* FIXME: Add HW fog support */
+#endif
+ default: return 0;
+ }
+}
+
+/* Initialize the extensions supported by this driver */
+void r128DDInitExtensions(GLcontext *ctx)
+{
+ /* FIXME: Are there other extensions to enable/disable??? */
+ gl_extensions_disable(ctx, "GL_EXT_shared_texture_palette");
+ gl_extensions_disable(ctx, "GL_EXT_paletted_texture");
+ gl_extensions_disable(ctx, "GL_EXT_point_parameters");
+ gl_extensions_disable(ctx, "ARB_imaging");
+ gl_extensions_disable(ctx, "GL_EXT_blend_minmax");
+ gl_extensions_disable(ctx, "GL_EXT_blend_logic_op");
+ gl_extensions_disable(ctx, "GL_EXT_blend_subtract");
+ gl_extensions_disable(ctx, "GL_INGR_blend_func_separate");
+
+ if (getenv("LIBGL_NO_MULTITEXTURE"))
+ gl_extensions_disable(ctx, "GL_ARB_multitexture");
+}
+
+/* Initialize the driver's misc functions */
+void r128DDInitDriverFuncs(GLcontext *ctx)
+{
+ ctx->Driver.Clear = r128DDClear;
+
+ ctx->Driver.GetBufferSize = r128DDGetBufferSize;
+ ctx->Driver.GetString = r128DDGetString;
+ ctx->Driver.Finish = r128DDFinish;
+ ctx->Driver.Flush = r128DDFlush;
+
+ ctx->Driver.Error = NULL;
+ ctx->Driver.GetParameteri = r128DDGetParameteri;
+
+ ctx->Driver.DrawPixels = NULL;
+ ctx->Driver.Bitmap = NULL;
+
+ ctx->Driver.RegisterVB = r128DDRegisterVB;
+ ctx->Driver.UnregisterVB = r128DDUnregisterVB;
+ ctx->Driver.BuildPrecalcPipeline = r128DDBuildPrecalcPipeline;
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_dd.h b/xc/lib/GL/mesa/src/drv/r128/r128_dd.h
new file mode 100644
index 000000000..91aa02586
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.h
@@ -0,0 +1,44 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_DD_H_
+#define _R128_DD_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void r128DDInitExtensions(GLcontext *ctx);
+extern void r128DDInitDriverFuncs(GLcontext *ctx);
+
+#endif
+#endif /* _R128_DD_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c
new file mode 100644
index 000000000..330e5a23d
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c
@@ -0,0 +1,551 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_state.h"
+#include "r128_vb.h"
+#include "r128_tris.h"
+#include "r128_fastpath.h"
+
+#include "mmath.h"
+#include "cva.h"
+#include "vertices.h"
+
+/* FIXME: These routines were copied from the i810 driver, and were only
+ slightly modified for the Rage 128. They still need to be optmizied
+ and cleaned up. Also, support for USE_RHW2 needs to be added. */
+
+typedef struct r128_fast_table {
+ r128BuildVerticesFunc build_vertices;
+ r128InterpFunc interp;
+} r128FastPathTable;
+
+#define POINT(x) r128DrawPointVB(r128ctx, &vert[x].v, psize)
+#define LINE(x,y) r128DrawLineVB(r128ctx, &vert[x].v, &vert[y].v, lwidth)
+#define TRI(x,y,z) r128DrawTriangleVB(r128ctx, &vert[x].v, &vert[y].v, &vert[z].v)
+
+/* Direct, and no clipping required. The clip funcs have not been
+ written yet, so this is only useful for the fast path. */
+#define RENDER_POINTS(start, count) \
+do { \
+ GLuint e; \
+ for (e = start; e <= count; e++) \
+ POINT(elt[e]); \
+} while (0)
+
+#define RENDER_LINE(i1, i) \
+do { \
+ GLuint e1 = elt[i1], e = elt[i]; \
+ LINE(e1, e); \
+} while (0)
+
+#define RENDER_TRI(i2, i1, i, pv, parity) \
+do { \
+ GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
+ if (parity) { \
+ GLuint tmp = e2; \
+ e2 = e1; \
+ e1 = tmp; \
+ } \
+ TRI(e2, e1, e); \
+} while (0)
+
+#define RENDER_QUAD(i3, i2, i1, i, pv) \
+do { \
+ GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
+ TRI(e3, e2, e); \
+ TRI(e2, e1, e); \
+} while (0)
+
+#define LOCAL_VARS \
+ r128VertexPtr vert = R128_DRIVER_DATA(VB)->verts; \
+ const GLuint *elt = VB->EltPtr->data; \
+ GLcontext *ctx = VB->ctx; \
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx); \
+ const GLfloat lwidth = ctx->Line.Width; \
+ const GLfloat psize = ctx->Point.Size; \
+ (void) lwidth; (void)psize; (void) vert;
+
+#define TAG(x) x##_r128_smooth_indirect
+#include "render_tmp.h"
+
+
+
+#define NEGATIVE(f) (f < 0)
+#define DIFFERENT_SIGNS(a,b) ((a*b) < 0)
+#define LINTERP(T, A, B) ((A) + (T) * ((B) - (A)))
+
+
+#define INTERP_RGBA(t, out, a, b) \
+do { \
+ int i; \
+ for (i = 0; i < 4; i++) { \
+ GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR(a[i]); \
+ GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR(b[i]); \
+ GLfloat fo = LINTERP(t, fa, fb); \
+ FLOAT_COLOR_TO_UBYTE_COLOR(out[i], fo); \
+ } \
+} while (0)
+
+
+#define CLIP(SGN, V, PLANE) \
+do { \
+ if (mask & PLANE) { \
+ GLuint *indata = inlist[in]; \
+ GLuint *outdata = inlist[in ^= 1]; \
+ GLuint nr = n; \
+ GLfloat *J = verts[indata[nr-1]].f; \
+ GLfloat dpJ = (SGN J[V]) + J[3]; \
+ \
+ inlist[0] = vlist1; \
+ for (i = n = 0 ; i < nr ; i++) { \
+ GLuint elt_i = indata[i]; \
+ GLfloat *I = verts[elt_i].f; \
+ GLfloat dpI = (SGN I[V]) + I[3]; \
+ \
+ if (DIFFERENT_SIGNS(dpI, dpJ)) { \
+ GLfloat *O = verts[next_vert].f; \
+ GLfloat t, *in, *out; \
+ \
+ if (NEGATIVE(dpI)) { \
+ t = dpI / (dpI - dpJ); \
+ in = I; \
+ out = J; \
+ } else { \
+ t = dpJ / (dpJ - dpI); \
+ in = J; \
+ out = I; \
+ } \
+ \
+ interp(t, O, in, out); \
+ \
+ clipmask[next_vert] = 0; \
+ outdata[n++] = next_vert++; \
+ } \
+ \
+ clipmask[elt_i] |= PLANE; /* don't set up */ \
+ \
+ if (!NEGATIVE(dpI)) { \
+ outdata[n++] = elt_i; \
+ clipmask[elt_i] &= ~PLANE; /* set up after all */ \
+ } \
+ \
+ J = I; \
+ dpJ = dpI; \
+ } \
+ \
+ if (n < 3) return; \
+ } \
+} while (0)
+
+#define LINE_CLIP(x,y,z,w,PLANE) \
+do { \
+ if (mask & PLANE) { \
+ GLfloat dpI = DOT4V(I,x,y,z,w); \
+ GLfloat dpJ = DOT4V(J,x,y,z,w); \
+ \
+ if (DIFFERENT_SIGNS(dpI, dpJ)) { \
+ GLfloat *O = verts[next_vert].f; \
+ GLfloat t = dpI / (dpI - dpJ); \
+ \
+ interp(t, O, I, J); \
+ \
+ clipmask[next_vert] = 0; \
+ \
+ if (NEGATIVE(dpI)) { \
+ clipmask[elts[0]] |= PLANE; \
+ I = O; \
+ elts[0] = next_vert++; \
+ } else { \
+ clipmask[elts[1]] |= PLANE; \
+ J = O; \
+ elts[1] = next_vert++; \
+ } \
+ } else if (NEGATIVE(dpI)) return; \
+ } \
+} while (0)
+
+
+static void r128TriClip(GLuint **p_elts,
+ r128Vertex *verts,
+ GLubyte *clipmask,
+ GLuint *p_next_vert,
+ GLubyte mask,
+ r128InterpFunc interp)
+{
+ GLuint *elts = *p_elts;
+ GLuint next_vert = *p_next_vert;
+ GLuint in = 0;
+ GLuint n = 3;
+ GLuint vlist1[VB_MAX_CLIPPED_VERTS];
+ GLuint vlist2[VB_MAX_CLIPPED_VERTS];
+ GLuint *inlist[2];
+ GLuint *out;
+ GLuint i;
+
+ inlist[0] = elts;
+ inlist[1] = vlist2;
+
+ CLIP(-,0,CLIP_RIGHT_BIT);
+ CLIP(+,0,CLIP_LEFT_BIT);
+ CLIP(-,1,CLIP_TOP_BIT);
+ CLIP(+,1,CLIP_BOTTOM_BIT);
+ CLIP(-,2,CLIP_FAR_BIT);
+ CLIP(+,2,CLIP_NEAR_BIT);
+
+ /* Convert the planar polygon to a list of triangles */
+ out = inlist[in];
+
+ for (i = 2 ; i < n ; i++) {
+ elts[0] = out[0];
+ elts[1] = out[i-1];
+ elts[2] = out[i];
+ elts += 3;
+ }
+
+ *p_next_vert = next_vert;
+ *p_elts = elts;
+}
+
+
+static void r128LineClip(GLuint **p_elts,
+ r128Vertex *verts,
+ GLubyte *clipmask,
+ GLuint *p_next_vert,
+ GLubyte mask,
+ r128InterpFunc interp)
+{
+ GLuint *elts = *p_elts;
+ GLfloat *I = verts[elts[0]].f;
+ GLfloat *J = verts[elts[1]].f;
+ GLuint next_vert = *p_next_vert;
+
+ LINE_CLIP(1,0,0,-1,CLIP_LEFT_BIT);
+ LINE_CLIP(-1,0,0,1,CLIP_RIGHT_BIT);
+ LINE_CLIP(0,1,0,-1,CLIP_TOP_BIT);
+ LINE_CLIP(0,-1,0,1,CLIP_BOTTOM_BIT);
+ LINE_CLIP(0,0,1,-1,CLIP_FAR_BIT);
+ LINE_CLIP(0,0,-1,1,CLIP_NEAR_BIT);
+
+ *p_next_vert = next_vert;
+ *p_elts += 2;
+}
+
+
+
+#define CLIP_POINT(e) \
+do { \
+ if (mask[e]) *out++ = e; \
+} while (0)
+
+#define CLIP_LINE(e1, e0) \
+do { \
+ GLubyte ormask = mask[e0] | mask[e1]; \
+ out[0] = e1; \
+ out[1] = e0; \
+ out += 2; \
+ if (ormask) { \
+ out-=2; \
+ if (!(mask[e0] & mask[e1])) { \
+ r128LineClip(&out, verts, mask, &next_vert, ormask, interp); \
+ } \
+ } \
+} while (0)
+
+#define CLIP_TRIANGLE(e2, e1, e0) \
+do { \
+ GLubyte ormask; \
+ out[0] = e2; \
+ out[1] = e1; \
+ out[2] = e0; \
+ out += 3; \
+ ormask = mask[e2] | mask[e1] | mask[e0]; \
+ if (ormask) { \
+ out -= 3; \
+ if (!(mask[e2] & mask[e1] & mask[e0])) { \
+ r128TriClip(&out, verts, mask, &next_vert, ormask, interp); \
+ } \
+ } \
+} while (0)
+
+
+
+/* Build a table of functions to clip each primitive type. These
+ * produce a list of elements in the appropriate 'reduced' primitive,
+ * ie (points, lines, triangles) containing all the clipped and
+ * unclipped primitives from the original list.
+ */
+#define LOCAL_VARS \
+ r128ContextPtr r128ctx = R128_CONTEXT(VB->ctx); \
+ r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); \
+ GLuint *elt = VB->EltPtr->data; \
+ r128Vertex *verts = r128VB->verts; \
+ GLuint next_vert = r128VB->last_vert; \
+ GLuint *out = r128VB->clipped_elements.data; \
+ GLubyte *mask = VB->ClipMask; \
+ r128InterpFunc interp = r128ctx->interp; \
+ (void) interp; (void) verts;
+
+#define POSTFIX \
+ r128VB->clipped_elements.count = out - r128VB->clipped_elements.data; \
+ r128VB->last_vert = next_vert;
+
+
+#define INIT(x)
+
+#define RENDER_POINTS(start, count) \
+do { \
+ GLuint i; \
+ for (i = start; i < count; i++) \
+ CLIP_POINT(elt[i]); \
+} while (0)
+
+#define RENDER_LINE(i1, i0) \
+do { \
+ CLIP_LINE(elt[i1], elt[i0]); \
+} while (0)
+
+#define RENDER_TRI(i2, i1, i0, pv, parity) \
+do { \
+ GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \
+ if (parity) e2 = elt[i1], e1 = elt[i2]; \
+ CLIP_TRIANGLE(e2, e1, e0); \
+} while (0)
+
+#define RENDER_QUAD(i3, i2, i1, i0, pv) \
+do { \
+ CLIP_TRIANGLE(elt[i3], elt[i2], elt[i0]); \
+ CLIP_TRIANGLE(elt[i2], elt[i1], elt[i0]); \
+} while (0)
+
+#define TAG(x) r128_clip_##x##_elt
+#include "render_tmp.h"
+
+
+/* Pack rgba and/or texture into the remaining half of a 32 byte vertex.
+ */
+#define CLIP_UBYTE_COLOR 4
+#define CLIP_UBYTE_B 0
+#define CLIP_UBYTE_G 1
+#define CLIP_UBYTE_R 2
+#define CLIP_UBYTE_A 3
+#define CLIP_S0 6
+#define CLIP_T0 7
+#define CLIP_S1 8
+#define CLIP_T1 9
+
+#define TYPE (0)
+#define TAG(x) x
+#include "r128_fasttmp.h"
+
+#define TYPE (R128_RGBA_BIT)
+#define TAG(x) x##_RGBA
+#include "r128_fasttmp.h"
+
+#define TYPE (R128_TEX0_BIT)
+#define TAG(x) x##_TEX0
+#include "r128_fasttmp.h"
+
+#define TYPE (R128_RGBA_BIT | R128_TEX0_BIT)
+#define TAG(x) x##_RGBA_TEX0
+#include "r128_fasttmp.h"
+
+#define TYPE (R128_RGBA_BIT | R128_TEX0_BIT | R128_TEX1_BIT)
+#define TAG(x) x##_RGBA_TEX0_TEX1
+#include "r128_fasttmp.h"
+
+/* This one *could* get away with sneaking TEX1 into the color and
+ * specular slots, thus fitting inside a cache line. Would be even
+ * better to switch to a smaller vertex.
+ */
+#define TYPE (R128_TEX0_BIT | R128_TEX1_BIT)
+#define TAG(x) x##_TEX0_TEX1
+#include "r128_fasttmp.h"
+
+
+
+/* Render elements directly from original list of vertices. */
+static void r128RenderElementsDirect(struct vertex_buffer *VB)
+{
+ GLcontext *ctx = VB->ctx;
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ GLenum prim = ctx->CVA.elt_mode;
+ GLuint nr = VB->EltPtr->count;
+ render_func func = render_tab_r128_smooth_indirect[prim];
+ GLuint p = 0;
+
+ if (r128ctx->dirty) r128UpdateHWState(r128ctx);
+
+ do {
+ func(VB, 0, nr, 0);
+ } while (ctx->Driver.MultipassFunc &&
+ ctx->Driver.MultipassFunc(VB, ++p));
+}
+
+/* Project vertices from clip to device space */
+static void r128ProjectVertices(struct vertex_buffer *VB)
+{
+ GLcontext *ctx = VB->ctx;
+ GLmatrix *mat = &ctx->Viewport.WindowMap;
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB);
+ GLfloat m[16];
+
+ m[MAT_SX] = mat->m[MAT_SX];
+ m[MAT_TX] = mat->m[MAT_TX];
+ m[MAT_SY] = -mat->m[MAT_SY];
+ m[MAT_TY] = -mat->m[MAT_TY] + r128ctx->driDrawable->h;
+ m[MAT_SZ] = mat->m[MAT_SZ];
+ m[MAT_TZ] = mat->m[MAT_TZ];
+
+ switch (ctx->Visual->DepthBits) {
+ case 16: m[MAT_SZ] /= 65536.0; m[MAT_TZ] /= 65536.0; break;
+ case 24: m[MAT_SZ] /= 16777216.0; m[MAT_TZ] /= 16777216.0; break;
+ case 32: m[MAT_SZ] /= 4294967296.0; m[MAT_TZ] /= 4294967296.0; break;
+ default: m[MAT_SZ] /= 65536.0; m[MAT_TZ] /= 65536.0; break;
+ }
+
+#if USE_RHW2
+ /* FIXME: Handle RHW2?? */
+ gl_project_v16(r128VB->verts[VB->CopyStart].f,
+ r128VB->verts[r128VB->last_vert].f,
+ m,
+ 16 * 4);
+#else
+ gl_project_v16(r128VB->verts[VB->CopyStart].f,
+ r128VB->verts[r128VB->last_vert].f,
+ m,
+ 16 * 4);
+#endif
+}
+
+/* Project clipped vertices from clip to device space */
+static void r128ProjectClippedVertices(struct vertex_buffer *VB)
+{
+ GLcontext *ctx = VB->ctx;
+ GLmatrix *mat = &ctx->Viewport.WindowMap;
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB);
+ GLfloat m[16];
+
+ m[MAT_SX] = mat->m[MAT_SX];
+ m[MAT_TX] = mat->m[MAT_TX];
+ m[MAT_SY] = -mat->m[MAT_SY];
+ m[MAT_TY] = -mat->m[MAT_TY] + r128ctx->driDrawable->h;
+ m[MAT_SZ] = mat->m[MAT_SZ];
+ m[MAT_TZ] = mat->m[MAT_TZ];
+
+ switch (ctx->Visual->DepthBits) {
+ case 16: m[MAT_SZ] /= 65536.0; m[MAT_TZ] /= 65536.0; break;
+ case 24: m[MAT_SZ] /= 16777216.0; m[MAT_TZ] /= 16777216.0; break;
+ case 32: m[MAT_SZ] /= 4294967296.0; m[MAT_TZ] /= 4294967296.0; break;
+ default: m[MAT_SZ] /= 65536.0; m[MAT_TZ] /= 65536.0; break;
+ }
+
+#if USE_RHW2
+ /* FIXME: Handle RHW2?? */
+ gl_project_clipped_v16(r128VB->verts[VB->CopyStart].f,
+ r128VB->verts[r128VB->last_vert].f,
+ m,
+ 16 * 4,
+ VB->ClipMask + VB->CopyStart);
+#else
+ gl_project_clipped_v16(r128VB->verts[VB->CopyStart].f,
+ r128VB->verts[r128VB->last_vert].f,
+ m,
+ 16 * 4,
+ VB->ClipMask + VB->CopyStart);
+#endif
+}
+
+static r128FastPathTable r128FastTab[0x80];
+
+/* Initialize the table of fast path support functions */
+void r128FastPathInit(void)
+{
+ r128_clip_render_init_elt();
+ render_init_r128_smooth_indirect();
+
+ r128_init_fastpath(&r128FastTab[0]);
+ r128_init_fastpath_RGBA(&r128FastTab[R128_RGBA_BIT]);
+ r128_init_fastpath_TEX0(&r128FastTab[R128_TEX0_BIT]);
+ r128_init_fastpath_RGBA_TEX0(&r128FastTab[R128_RGBA_BIT|R128_TEX0_BIT]);
+ r128_init_fastpath_TEX0_TEX1(&r128FastTab[R128_TEX0_BIT|R128_TEX1_BIT]);
+ r128_init_fastpath_RGBA_TEX0_TEX1(&r128FastTab[R128_RGBA_BIT|R128_TEX0_BIT|
+ R128_TEX1_BIT]);
+}
+
+#define VALID_SETUP (R128_RGBA_BIT | R128_TEX0_BIT | R128_TEX1_BIT)
+
+void r128FastPath(struct vertex_buffer *VB)
+{
+ GLcontext *ctx = VB->ctx;
+ GLenum prim = ctx->CVA.elt_mode;
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128FastPathTable *tab = &r128FastTab[r128ctx->SetupIndex & VALID_SETUP];
+ GLuint do_cliptest = 1;
+
+ gl_prepare_arrays_cva(VB); /* still need this */
+
+ /* Reserve enough space for the pathological case */
+ if (VB->EltPtr->count * 12 > R128_DRIVER_DATA(VB)->size) {
+ r128ResizeVB(VB, VB->EltPtr->count * 12);
+ do_cliptest = 1;
+ }
+
+ tab->build_vertices(VB, do_cliptest); /* object->clip space */
+
+ if (r128ctx->dirty) r128UpdateHWState(r128ctx);
+
+ if (VB->ClipOrMask) {
+ if (!VB->ClipAndMask) {
+ render_func *clip = r128_clip_render_tab_elt;
+
+ r128ctx->interp = tab->interp;
+ clip[prim](VB, 0, VB->EltPtr->count, 0); /* build new elts */
+ ctx->CVA.elt_mode = gl_reduce_prim[prim];
+ VB->EltPtr = &(R128_DRIVER_DATA(VB)->clipped_elements);
+ r128ProjectClippedVertices(VB); /* clip->device space */
+ r128RenderElementsDirect(VB); /* render using new list */
+ }
+ } else {
+ r128ProjectVertices(VB); /* clip->device space */
+ r128RenderElementsDirect(VB); /* render using orig list */
+ }
+
+ /* This indicates that there is no cached data to reuse */
+ VB->pipeline->data_valid = 0;
+ VB->pipeline->new_state = 0;
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.h b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.h
new file mode 100644
index 000000000..47bb92049
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.h
@@ -0,0 +1,48 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_FASTPATH_H_
+#define _R128_FASTPATH_H_
+
+typedef void (*r128BuildVerticesFunc)(struct vertex_buffer *VB,
+ GLuint do_cliptest);
+typedef void (*r128InterpFunc)(GLfloat t,
+ GLfloat *result,
+ const GLfloat *in,
+ const GLfloat *out);
+
+extern void r128FastPathInit(void);
+extern void r128FastPath(struct vertex_buffer *VB);
+
+#endif /* _R128_FASTPATH_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h b/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h
new file mode 100644
index 000000000..e76dd52b4
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h
@@ -0,0 +1,155 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+/* FIXME: These routines were copied from the i810 driver, and were only
+ slightly modified for the Rage 128. They still need to be optmizied
+ and cleaned up. Also, support for USE_RHW2 needs to be added. */
+
+/* The first part of setup is applied to all vertices, clipped or
+ * unclipped. This data w!ill be used for clipping, and then all
+ * vertices with a zero clipmask will be projected to device space.
+ *
+ * This could be split into several loops, but - it seems that the
+ * large stride of the fxVertices makes cache issues the big
+ * performance factor, and that multiple loops mean multiple cache
+ * misses....
+ */
+static void TAG(r128_setup_full)(struct vertex_buffer *VB, GLuint do_cliptest)
+{
+ GLcontext *ctx = VB->ctx;
+ r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB);
+ const GLfloat *m = ctx->ModelProjectMatrix.m;
+ GLuint start = VB->CopyStart;
+ GLuint count = VB->Count;
+ GLuint i;
+
+ gl_xform_points3_v16_general(r128VB->verts[start].f,
+ m,
+ VB->ObjPtr->start,
+ VB->ObjPtr->stride,
+ count - start);
+
+ if (do_cliptest) {
+ VB->ClipAndMask = ~0;
+ VB->ClipOrMask = 0;
+ gl_cliptest_points4_v16(r128VB->verts[start].f,
+ r128VB->verts[count].f,
+ &(VB->ClipOrMask),
+ &(VB->ClipAndMask),
+ VB->ClipMask + start);
+ }
+
+ /* These branches are all resolved at compile time. Hopefully all
+ * the pointers are valid addresses even when not enabled.
+ */
+ if (TYPE) {
+ GLubyte *color = VB->ColorPtr->start;
+ GLfloat *tex0_data = VB->TexCoordPtr[0]->start;
+ GLfloat *tex1_data = VB->TexCoordPtr[1]->start;
+
+ GLuint color_stride = VB->ColorPtr->stride;
+ GLuint tex0_stride = VB->TexCoordPtr[0]->stride;
+ GLuint tex1_stride = VB->TexCoordPtr[1]->stride;
+
+ GLfloat *f = r128VB->verts[start].f;
+
+ for (i = start ; i < count ; i++, f += 16) {
+ if (TYPE & R128_RGBA_BIT) {
+ GLubyte *b = (GLubyte *)&f[CLIP_UBYTE_COLOR];
+ GLubyte *col = color; color += color_stride;
+ b[CLIP_UBYTE_R] = col[0];
+ b[CLIP_UBYTE_G] = col[1];
+ b[CLIP_UBYTE_B] = col[2];
+ b[CLIP_UBYTE_A] = col[3];
+ }
+ if (TYPE & R128_TEX0_BIT) {
+ f[CLIP_S0] = tex0_data[0];
+ f[CLIP_T0] = tex0_data[1];
+ STRIDE_F(tex0_data, tex0_stride);
+ }
+ if (TYPE & R128_TEX1_BIT) {
+ f[CLIP_S1] = tex1_data[0];
+ f[CLIP_T1] = tex1_data[1];
+ STRIDE_F(tex1_data, tex1_stride);
+ }
+ }
+ }
+
+ r128VB->clipped_elements.count = start;
+ r128VB->last_vert = count;
+}
+
+
+/* Changed to just put the interp func instead of the whole clip
+ * routine into the header. Less code and better chance of doing some
+ * of this stuff in assembly.
+ */
+static void TAG(r128_interp_vert)(GLfloat t,
+ GLfloat *O,
+ const GLfloat *I,
+ const GLfloat *J)
+{
+ O[0] = LINTERP(t, I[0], J[0]);
+ O[1] = LINTERP(t, I[1], J[1]);
+ O[2] = LINTERP(t, I[2], J[2]);
+ O[3] = LINTERP(t, I[3], J[3]);
+
+ if (TYPE & R128_RGBA_BIT) {
+ INTERP_RGBA(t,
+ ((GLubyte *)&(O[4])),
+ ((GLubyte *)&(I[4])),
+ ((GLubyte *)&(J[4])));
+ }
+
+ if (TYPE & R128_TEX0_BIT) {
+ O[6] = LINTERP(t, I[6], J[6]);
+ O[7] = LINTERP(t, I[7], J[7]);
+ }
+
+ if (TYPE & R128_TEX1_BIT) {
+ O[8] = LINTERP(t, I[8], J[8]);
+ O[9] = LINTERP(t, I[9], J[9]);
+ }
+}
+
+
+static void TAG(r128_init_fastpath)(r128FastPathTable *tab)
+{
+ tab->build_vertices = TAG(r128_setup_full);
+ tab->interp = TAG(r128_interp_vert);
+}
+
+#undef TYPE
+#undef TAG
+#undef SIZE
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_init.h b/xc/lib/GL/mesa/src/drv/r128/r128_init.h
new file mode 100644
index 000000000..fcaf70a51
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_init.h
@@ -0,0 +1,92 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_INIT_H_
+#define _R128_INIT_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include <X11/Xlibint.h>
+
+#include "types.h"
+#include "xf86drm.h"
+#include "dri_tmm.h"
+#include "dri_mesaint.h"
+
+#include "r128_screen.h"
+#include "r128_context.h"
+
+/* NOTE: The vertex buffer code is currently unstable because of the
+ switches between CCE and MMIO mode in the X server. Fixing the X
+ server to use the CCE should fix this problem. So, for now, it is
+ recommended that you do not use it. */
+
+#define DEBUG 1
+#define DEBUG_LOCKING 1
+#define USE_FAST_PATH 1
+#define USE_USER_SPACE_RING 0
+
+
+#if DEBUG
+
+#include <stdio.h>
+#define R128_DEBUG(p) \
+ do { \
+ printf p ; \
+ fflush(stdout); \
+ } while (0)
+
+extern int R128_DEBUG_FLAGS;
+
+#define DEBUG_VERBOSE_2D 0x0001
+#define DEBUG_VERBOSE_CCE 0x0008
+#define DEBUG_VERBOSE_OUTREG 0x0010
+#define DEBUG_ALWAYS_SYNC 0x0040
+#define DEBUG_VERBOSE_MSG 0x0080
+#define DEBUG_NO_OUTRING 0x0100
+#define DEBUG_NO_OUTREG 0x0200
+#define DEBUG_VERBOSE_API 0x0400
+#define DEBUG_VALIDATE_RING 0x0800
+#define DEBUG_VERBOSE_LRU 0x1000
+#define DEBUG_VERBOSE_DRI 0x2000
+#define DEBUG_VERBOSE_IOCTL 0x4000
+
+#else
+
+#define R128_DEBUG_FLAGS 0
+
+#endif
+
+#endif
+#endif /* _R128_INIT_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_lock.h b/xc/lib/GL/mesa/src/drv/r128/r128_lock.h
new file mode 100644
index 000000000..7fd81f807
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_lock.h
@@ -0,0 +1,134 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_LOCK_H_
+#define _R128_LOCK_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+/* Turn DEBUG_LOCKING on to find locking conflicts (see r128_init.h) */
+#if DEBUG_LOCKING
+extern char *prevLockFile;
+extern int prevLockLine;
+
+#define DEBUG_LOCK() \
+ do { \
+ prevLockFile = (__FILE__); \
+ prevLockLine = (__LINE__); \
+ } while (0)
+
+#define DEBUG_RESET() \
+ do { \
+ prevLockFile = 0; \
+ prevLockLine = 0; \
+ } while (0)
+
+#define DEBUG_CHECK_LOCK() \
+ do { \
+ if (prevLockFile) { \
+ fprintf(stderr, \
+ "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \
+ prevLockFile, prevLockLine, __FILE__, __LINE__); \
+ exit(1); \
+ } \
+ } while (0)
+
+#else
+
+#define DEBUG_LOCK()
+#define DEBUG_RESET()
+#define DEBUG_CHECK_LOCK()
+
+#endif
+
+/*
+ * !!! We may want to separate locks from locks with validation. This
+ * could be used to improve performance for those things commands that
+ * do not do any drawing !!!
+ */
+
+/* Lock the hardware using the current context */
+#define LOCK_HARDWARE(CC) \
+ do { \
+ char __ret = 0; \
+ __DRIcontextPrivate *cPriv = CC->driContext; \
+ __DRIscreenPrivate *sPriv = CC->r128Screen->driScreen; \
+ \
+ DEBUG_CHECK_LOCK(); \
+ DRM_CAS(&sPriv->pSAREA->lock, cPriv->hHWContext, \
+ DRM_LOCK_HELD|cPriv->hHWContext, __ret); \
+ if (__ret) { \
+ /* We lost the context, so we need to request the lock from \
+ the kernel and update our state. */ \
+ drmGetLock(sPriv->fd, cPriv->hHWContext, 0); \
+ XMesaUpdateState(cPriv); \
+ } \
+ DEBUG_LOCK(); \
+ } while (0)
+
+/* Unlock the hardware using the current context */
+#define UNLOCK_HARDWARE(CC) \
+ do { \
+ __DRIcontextPrivate *cPriv = CC->driContext; \
+ __DRIscreenPrivate *sPriv = CC->r128Screen->driScreen; \
+ \
+ DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, cPriv->hHWContext); \
+ DEBUG_RESET(); \
+ } while (0)
+
+/*
+ * This pair of macros makes a loop over the drawing operations, so it
+ * is not self contained and does not have the nice single statement
+ * semantics of most macros.
+ */
+#define BEGIN_CLIP_LOOP(CC) \
+ do { \
+ __DRIdrawablePrivate *_dPriv = CC->driDrawable; \
+ XF86DRIClipRectPtr _pc = _dPriv->pClipRects; \
+ int _nc, _sc; \
+ \
+ for (_nc = _dPriv->numClipRects; _nc > 0; _nc -= 3, _pc += 3) { \
+ _sc = (_nc <= 3) ? _nc : 3; \
+ r128SetClipRects(CC, _pc, _sc)
+
+/* FIXME: This should be a function call to turn off aux clipping */
+#define END_CLIP_LOOP(CC) \
+ R128CCE0(R128_CCE_PACKET0, R128_AUX_SC_CNTL, 0); \
+ R128CCE(0x00000000); \
+ R128CCE_SUBMIT_PACKETS(); \
+ } \
+ } while (0)
+
+#endif
+#endif /* _R128_LOCK_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_mesa.h b/xc/lib/GL/mesa/src/drv/r128/r128_mesa.h
new file mode 100644
index 000000000..3a697b466
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_mesa.h
@@ -0,0 +1,43 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_MESA_H_
+#define _R128_MESA_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#define R128_CONTEXT(ctx) ((r128ContextPtr)(ctx->DriverCtx))
+
+#endif
+#endif /* _R128_MESA_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c
new file mode 100644
index 000000000..55487ffcd
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c
@@ -0,0 +1,126 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_vb.h"
+#include "r128_fastpath.h"
+#include "r128_pipeline.h"
+
+#include "types.h"
+
+static struct gl_pipeline_stage r128FastStage = {
+ "R128 Fast Path",
+ (PIPE_OP_VERT_XFORM |
+ PIPE_OP_RAST_SETUP_0 |
+ PIPE_OP_RAST_SETUP_1 |
+ PIPE_OP_RENDER),
+ PIPE_PRECALC,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ r128FastPath
+};
+
+/* Build the PRECALC pipeline with our stage, if possible. Otherwise,
+ return GL_FALSE */
+GLboolean r128DDBuildPrecalcPipeline(GLcontext *ctx)
+{
+#if USE_FAST_PATH
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ struct gl_pipeline *pipe = &ctx->CVA.pre;
+
+ if (r128ctx->RenderIndex == 0 &&
+ !(ctx->Enabled & (TEXTURE0_3D |
+ TEXTURE1_3D |
+ ENABLE_TEXMAT0 |
+ ENABLE_TEXMAT1 |
+ ENABLE_TEXGEN0 |
+ ENABLE_TEXGEN1 |
+ ENABLE_USERCLIP |
+ ENABLE_LIGHT |
+ ENABLE_FOG)) &&
+ (ctx->Array.Flags & (VERT_OBJ_234 |
+ VERT_TEX0_4 |
+ VERT_TEX1_4 |
+ VERT_ELT)) == (VERT_OBJ_23 |
+ VERT_ELT)) {
+ pipe->stages[0] = &r128FastStage;
+ pipe->stages[1] = 0;
+ pipe->new_inputs = ctx->RenderFlags & VERT_DATA;
+ pipe->ops = pipe->stages[0]->ops;
+
+ r128ctx->useFastPath = GL_TRUE;
+ return GL_TRUE;
+ }
+
+ if (r128ctx->useFastPath) {
+ r128ctx->useFastPath = GL_FALSE;
+
+ ctx->CVA.VB->ClipOrMask = 0;
+ ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS;
+ ctx->Array.NewArrayState |= ctx->Array.Summary;
+ }
+#endif
+
+ return GL_FALSE;
+}
+
+/* Register the pipeline with our stages included */
+GLuint r128RegisterPipelineStages(struct gl_pipeline_stage *out,
+ const struct gl_pipeline_stage *in,
+ GLuint nr)
+{
+#if USE_FAST_PATH
+ int i;
+
+ for (i = 0; i < nr; i++) {
+ out[i] = in[i];
+ switch (in[i].ops) {
+ case PIPE_OP_RAST_SETUP_0:
+ out[i].cva_state_change = (NEW_LIGHTING |
+ NEW_TEXTURING |
+ NEW_RASTER_OPS);
+ out[i].state_change = ~0;
+ out[i].check = r128CheckPartialRasterSetup;
+ out[i].run = r128PartialRasterSetup;
+ break;
+
+ case PIPE_OP_RAST_SETUP_0|PIPE_OP_RAST_SETUP_1:
+ out[i].run = r128DoRasterSetup;
+ break;
+ }
+ }
+#endif
+
+ return nr;
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h
new file mode 100644
index 000000000..280e6b943
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h
@@ -0,0 +1,43 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_PIPELINE_H_
+#define _R128_PIPELINE_H_
+
+extern GLboolean r128DDBuildPrecalcPipeline(GLcontext *ctx);
+extern GLuint r128RegisterPipelineStages(struct gl_pipeline_stage *out,
+ const struct gl_pipeline_stage *in,
+ GLuint nr);
+
+#endif /* _R128_PIPELINE_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c
new file mode 100644
index 000000000..b385271f4
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c
@@ -0,0 +1,258 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_dri.h"
+#include "r128_reg.h"
+
+#include "r128_init.h"
+#include "r128_context.h"
+#include "r128_xmesa.h"
+#include "r128_cce.h"
+#include "r128_tris.h"
+#include "r128_vb.h"
+#include "r128_fastpath.h"
+
+#include <sys/mman.h>
+
+/* Create the device specific screen private data struct */
+r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv)
+{
+ r128ScreenPtr r128Screen;
+ R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv;
+
+ /* Allocate the private area */
+ r128Screen = (r128ScreenPtr)Xmalloc(sizeof(*r128Screen));
+ if (!r128Screen) return NULL;
+
+ /* This is first since which regions we map depends on whether or
+ not we are using a PCI card */
+ r128Screen->IsPCI = r128DRIPriv->IsPCI;
+
+ r128Screen->mmioRgn.handle = r128DRIPriv->registerHandle;
+ r128Screen->mmioRgn.size = r128DRIPriv->registerSize;
+ if (drmMap(sPriv->fd,
+ r128Screen->mmioRgn.handle,
+ r128Screen->mmioRgn.size,
+ (drmAddressPtr)&r128Screen->mmio)) {
+ Xfree(r128Screen);
+ return NULL;
+ }
+
+ if (!r128Screen->IsPCI) {
+ r128Screen->ringRgn.handle = r128DRIPriv->ringHandle;
+ r128Screen->ringRgn.size = r128DRIPriv->ringMapSize;
+ if (drmMap(sPriv->fd,
+ r128Screen->ringRgn.handle,
+ r128Screen->ringRgn.size,
+ (drmAddressPtr)&r128Screen->ring)) {
+ drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
+ Xfree(r128Screen);
+ return NULL;
+ }
+
+ r128Screen->ringReadRgn.handle = r128DRIPriv->ringReadPtrHandle;
+ r128Screen->ringReadRgn.size = r128DRIPriv->ringReadMapSize;
+ if (drmMap(sPriv->fd,
+ r128Screen->ringReadRgn.handle,
+ r128Screen->ringReadRgn.size,
+ (drmAddressPtr)&r128Screen->ringReadPtr)) {
+ drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size);
+ drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
+ Xfree(r128Screen);
+ return NULL;
+ }
+
+ r128Screen->vbRgn.handle = r128DRIPriv->vbHandle;
+ r128Screen->vbRgn.size = r128DRIPriv->vbMapSize;
+ r128Screen->vbOffset = r128DRIPriv->vbOffset;
+ if (drmMap(sPriv->fd,
+ r128Screen->vbRgn.handle,
+ r128Screen->vbRgn.size,
+ (drmAddressPtr)&r128Screen->vb)) {
+ drmUnmap((drmAddress)r128Screen->ringReadPtr,
+ r128Screen->ringReadRgn.size);
+ drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size);
+ drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
+ Xfree(r128Screen);
+ return NULL;
+ }
+ r128Screen->vbOffset = r128DRIPriv->vbOffset;
+ r128Screen->vbBufSize = r128DRIPriv->vbBufSize;
+
+ r128Screen->indRgn.handle = r128DRIPriv->indHandle;
+ r128Screen->indRgn.size = r128DRIPriv->indMapSize;
+ if (drmMap(sPriv->fd,
+ r128Screen->indRgn.handle,
+ r128Screen->indRgn.size,
+ (drmAddressPtr)&r128Screen->ind)) {
+ drmUnmap((drmAddress)r128Screen->vb, r128Screen->vbRgn.size);
+ drmUnmap((drmAddress)r128Screen->ringReadPtr,
+ r128Screen->ringReadRgn.size);
+ drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size);
+ drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
+ Xfree(r128Screen);
+ return NULL;
+ }
+
+ r128Screen->agpTexRgn.handle = r128DRIPriv->agpTexHandle;
+ r128Screen->agpTexRgn.size = r128DRIPriv->agpTexMapSize;
+ if (drmMap(sPriv->fd,
+ r128Screen->agpTexRgn.handle,
+ r128Screen->agpTexRgn.size,
+ (drmAddressPtr)&r128Screen->agpTex)) {
+ drmUnmap((drmAddress)r128Screen->ind, r128Screen->indRgn.size);
+ drmUnmap((drmAddress)r128Screen->vb, r128Screen->vbRgn.size);
+ drmUnmap((drmAddress)r128Screen->ringReadPtr,
+ r128Screen->ringReadRgn.size);
+ drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size);
+ drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
+ Xfree(r128Screen);
+ return NULL;
+ }
+ r128Screen->agpTexOffset = r128DRIPriv->agpTexOffset;
+
+ if (!(r128Screen->vbBufs = drmMapBufs(sPriv->fd))) {
+ drmUnmap((drmAddress)r128Screen->agpTex,
+ r128Screen->agpTexRgn.size);
+ drmUnmap((drmAddress)r128Screen->ind, r128Screen->indRgn.size);
+ drmUnmap((drmAddress)r128Screen->vb, r128Screen->vbRgn.size);
+ drmUnmap((drmAddress)r128Screen->ringReadPtr,
+ r128Screen->ringReadRgn.size);
+ drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size);
+ drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
+ Xfree(r128Screen);
+ return NULL;
+ }
+ }
+
+ r128Screen->deviceID = r128DRIPriv->deviceID;
+
+ r128Screen->width = r128DRIPriv->width;
+ r128Screen->height = r128DRIPriv->height;
+ r128Screen->depth = r128DRIPriv->depth;
+ r128Screen->bpp = r128DRIPriv->bpp;
+ r128Screen->pixel_code = (r128Screen->bpp != 16 ?
+ r128Screen->bpp :
+ r128Screen->depth);
+
+ r128Screen->fb = sPriv->pFB;
+ r128Screen->fbOffset = sPriv->fbOrigin;
+ r128Screen->fbStride = sPriv->fbStride;
+ r128Screen->fbSize = sPriv->fbSize;
+
+ r128Screen->fbX = r128DRIPriv->fbX;
+ r128Screen->fbY = r128DRIPriv->fbY;
+ r128Screen->backX = r128DRIPriv->backX;
+ r128Screen->backY = r128DRIPriv->backY;
+ r128Screen->depthX = r128DRIPriv->depthX;
+ r128Screen->depthY = r128DRIPriv->depthY;
+
+ r128Screen->texOffset[R128_LOCAL_TEX_HEAP] = (r128DRIPriv->textureY *
+ r128Screen->fbStride +
+ r128DRIPriv->textureX *
+ (r128Screen->bpp/8));
+ r128Screen->texSize[R128_LOCAL_TEX_HEAP] = r128DRIPriv->textureSize;
+ r128Screen->log2TexGran[R128_LOCAL_TEX_HEAP] = r128DRIPriv->log2TexGran;
+
+ if (r128Screen->IsPCI) {
+ r128Screen->texOffset[R128_AGP_TEX_HEAP] = 0;
+ r128Screen->texSize[R128_AGP_TEX_HEAP] = 0;
+ r128Screen->log2TexGran[R128_AGP_TEX_HEAP] = 0;
+ r128Screen->NRTexHeaps = R128_NR_TEX_HEAPS-1;
+ } else {
+ r128Screen->texOffset[R128_AGP_TEX_HEAP] = 0;
+ r128Screen->texSize[R128_AGP_TEX_HEAP] =
+ r128DRIPriv->agpTexMapSize;
+ r128Screen->log2TexGran[R128_AGP_TEX_HEAP] =
+ r128DRIPriv->log2AGPTexGran;
+ r128Screen->NRTexHeaps = R128_NR_TEX_HEAPS;
+ }
+
+#if 1
+ /* FIXME: For testing only */
+ if (getenv("LIBGL_SHOW_BUFFERS")) {
+ r128Screen->backX = 0;
+ r128Screen->backY = r128DRIPriv->height/2;
+ r128Screen->depthX = r128DRIPriv->width/2;
+ r128Screen->depthY = r128DRIPriv->height/2;
+ }
+#endif
+
+ r128Screen->CCEMode = r128DRIPriv->CCEMode;
+ r128Screen->CCEFifoSize = r128DRIPriv->CCEFifoSize;
+
+ r128Screen->ringEntries = r128DRIPriv->ringSize/sizeof(CARD32);
+ if (!r128Screen->IsPCI) {
+ r128Screen->ringStartPtr = (int *)r128Screen->ring;
+ r128Screen->ringEndPtr = (int *)(r128Screen->ring
+ + r128DRIPriv->ringSize);
+ }
+
+ r128Screen->MMIOFifoSlots = 0;
+ r128Screen->CCEFifoSlots = 0;
+
+ r128Screen->CCEFifoAddr = R128_PM4_FIFO_DATA_EVEN;
+
+ r128Screen->SAREA = (R128SAREAPrivPtr)((char *)sPriv->pSAREA +
+ sizeof(XF86DRISAREARec));
+
+ r128Screen->driScreen = sPriv;
+
+ r128FastPathInit();
+ r128TriangleFuncsInit();
+ r128SetupInit();
+
+ return r128Screen;
+}
+
+/* Destroy the device specific screen private data struct */
+void r128DestroyScreen(__DRIscreenPrivate *sPriv)
+{
+ r128ScreenPtr r128Screen = (r128ScreenPtr)sPriv->private;
+
+ if (!r128Screen->IsPCI) {
+ drmUnmapBufs(r128Screen->vbBufs);
+
+ drmUnmap((drmAddress)r128Screen->agpTex, r128Screen->agpTexRgn.size);
+ drmUnmap((drmAddress)r128Screen->ind, r128Screen->indRgn.size);
+ drmUnmap((drmAddress)r128Screen->vb, r128Screen->vbRgn.size);
+ drmUnmap((drmAddress)r128Screen->ringReadPtr,
+ r128Screen->ringReadRgn.size);
+ drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size);
+ }
+ drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
+
+ Xfree(r128Screen);
+ sPriv->private = NULL;
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_screen.h b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h
new file mode 100644
index 000000000..02deb64e9
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h
@@ -0,0 +1,129 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_SCREEN_H_
+#define _R128_SCREEN_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "r128_sarea.h"
+
+typedef struct {
+ drmHandle handle; /* Handle to the DRM region */
+ drmSize size; /* Size of the DRM region */
+} r128RegionRec, *r128RegionPtr;
+
+typedef struct {
+ /* MMIO register data */
+ r128RegionRec mmioRgn;
+ unsigned char *mmio;
+
+ /* CCE ring buffer data */
+ r128RegionRec ringRgn;
+ unsigned char *ring;
+
+ /* CCE ring read pointer data */
+ r128RegionRec ringReadRgn;
+
+ /* CCE vertex buffer data */
+ r128RegionRec vbRgn;
+ unsigned char *vb;
+ int vbOffset;
+ int vbBufSize;
+ drmBufMapPtr vbBufs;
+
+ /* CCE indirect buffer data */
+ r128RegionRec indRgn;
+ unsigned char *ind;
+
+ /* CCE AGP Texture data */
+ r128RegionRec agpTexRgn;
+ unsigned char *agpTex;
+ int agpTexOffset;
+
+ /* Frame buffer data */
+ unsigned char *fb;
+ unsigned long fbOffset;
+ int fbStride;
+ int fbSize;
+
+ int IsPCI; /* Current card is a PCI card */
+
+ int CCEMode; /* CCE mode that server/clients use */
+ int CCEFifoSize; /* Size of the CCE command FIFO */
+
+ /* CCE ring buffer data */
+ int ringEntries;
+
+ volatile int *ringReadPtr; /* Pointer to current read addr */
+ int *ringStartPtr; /* Pointer to end of ring buffer */
+ int *ringEndPtr; /* Pointer to end of ring buffer */
+
+ /* DRI screen private data */
+ int deviceID; /* PCI device ID */
+ int width; /* Width in pixels of display */
+ int height; /* Height in scanlines of display */
+ int depth; /* Depth of display (8, 15, 16, 24) */
+ int bpp; /* Bit depth of disp (8, 16, 24, 32) */
+ int pixel_code; /* 8, 15, 16, 24, 32 */
+
+ int fbX; /* Start of frame buffer */
+ int fbY;
+ int backX; /* Start of shared back buffer */
+ int backY;
+ int depthX; /* Start of shared depth buffer */
+ int depthY;
+
+ /* Shared texture data */
+ int NRTexHeaps;
+ int texOffset[R128_NR_TEX_HEAPS];
+ int texSize[R128_NR_TEX_HEAPS];
+ int log2TexGran[R128_NR_TEX_HEAPS];
+
+ int MMIOFifoSlots; /* Free slots in the FIFO (64 max) */
+ int CCEFifoSlots; /* Free slots in the CCE FIFO */
+
+ int CCEFifoAddr; /* MMIO offset to write next CCE
+ value (only used when CCE is
+ in PIO mode). */
+ R128SAREAPrivPtr SAREA; /* Pointer to SAREA private data */
+
+ __DRIscreenPrivate *driScreen;
+} r128ScreenRec, *r128ScreenPtr;
+
+r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv);
+void r128DestroyScreen(__DRIscreenPrivate *sPriv);
+
+#endif
+#endif /* _R128_SCREEN_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_span.c b/xc/lib/GL/mesa/src/drv/r128/r128_span.c
new file mode 100644
index 000000000..b5d1774fd
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.c
@@ -0,0 +1,329 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Keith Whitwell <keith@precisioninsight.com>
+ * Gareth Hughes <gareth@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_state.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+#include "r128_span.h"
+
+#define DBG 0
+
+#define LOCAL_VARS \
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx); \
+ r128ScreenPtr r128scrn = r128ctx->r128Screen; \
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \
+ GLuint pitch = r128scrn->fbStride; \
+ GLuint height = dPriv->h; \
+ char *buf = (char *)(r128scrn->fb + \
+ (r128ctx->drawX + dPriv->x) * (r128scrn->bpp/8) + \
+ (r128ctx->drawY + dPriv->y) * pitch); \
+ char *read_buf = (char *)(r128scrn->fb + \
+ (r128ctx->readX + dPriv->x) * (r128scrn->bpp/8)+\
+ (r128ctx->readY + dPriv->y) * pitch); \
+ GLushort p; \
+ (void) read_buf; (void) buf; (void) p
+
+#define LOCAL_DEPTH_VARS \
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx); \
+ r128ScreenPtr r128scrn = r128ctx->r128Screen; \
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \
+ GLuint pitch = r128scrn->fbStride; \
+ GLuint height = dPriv->h; \
+ char *buf = (char *)(r128scrn->fb + \
+ (r128scrn->depthX + dPriv->x) * (r128scrn->bpp/8) + \
+ (r128scrn->depthY + dPriv->y) * pitch); \
+ (void) buf
+
+#define INIT_MONO_PIXEL(p) \
+ p = R128_CONTEXT(ctx)->Color
+
+#define CLIPPIXEL(_x, _y) \
+ ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy))
+
+
+#define CLIPSPAN(_x, _y, _n, _x1, _n1, _i) \
+ if (( _y < miny) || (_y >= maxy)) { \
+ _n1 = 0, _x1 = x; \
+ } else { \
+ _n1 = _n; \
+ _x1 = _x; \
+ if (_x1 < minx) _i += (minx - _x1), _x1 = minx; \
+ if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx) + 1; \
+ }
+
+#define Y_FLIP(_y) (height - _y - 1)
+
+
+#define HW_LOCK() \
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx); \
+ LOCK_HARDWARE(r128ctx); \
+ R128CCE_WAIT_FOR_IDLE(r128ctx);
+
+#define HW_CLIPLOOP() \
+ do { \
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \
+ int _nc = dPriv->numClipRects; \
+ \
+ while (_nc--) { \
+ int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
+ int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
+ int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
+ int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;
+
+#define HW_ENDCLIPLOOP() \
+ } \
+ } while (0)
+
+#define HW_UNLOCK() \
+ UNLOCK_HARDWARE(r128ctx)
+
+
+
+/* 16 bit, RGB565 color spanline and pixel functions */
+#define WRITE_RGBA(_x, _y, r, g, b, a) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \
+ (((int)g & 0xfc) << 3) | \
+ (((int)b & 0xf8) >> 3) )
+
+#define WRITE_PIXEL(_x, _y, p) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = p
+
+#define READ_RGBA(rgba, _x, _y) \
+ do { \
+ GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
+ rgba[0] = (p >> 8) & 0xf8; \
+ rgba[1] = (p >> 3) & 0xfc; \
+ rgba[2] = (p << 3) & 0xf8; \
+ rgba[3] = 0xff; \
+ } while (0)
+
+#define TAG(x) r128##x##_RGB565
+#include "spantmp.h"
+
+
+
+/* 15 bit, ARGB1555 color spanline and pixel functions */
+#define WRITE_RGBA(_x, _y, r, g, b, a) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \
+ ((g & 0xf8) << 2) | \
+ ((b & 0xf8) >> 3) | \
+ ((a) ? 0x8000 : 0))
+
+#define WRITE_PIXEL(_x, _y, p) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = p
+
+#define READ_RGBA(rgba, _x, _y) \
+ do { \
+ GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
+ rgba[0] = (p >> 7) & 0xf8; \
+ rgba[1] = (p >> 2) & 0xf8; \
+ rgba[2] = (p << 3) & 0xf8; \
+ rgba[3] = (p & 0x8000) ? 0xff : 0; \
+ } while (0)
+
+#define TAG(x) r128##x##_ARGB1555
+#include "spantmp.h"
+
+
+
+/* 16 bit depthbuffer functions */
+#define WRITE_DEPTH(_x, _y, d) \
+ *(GLdepth *)(buf + _x*2 + _y*pitch) = d
+
+#define READ_DEPTH(d, _x, _y) \
+ d = *(GLdepth *)(buf + _x*2 + _y*pitch)
+
+#define TAG(x) r128##x##_16
+#include "depthtmp.h"
+
+
+
+/* 24 bit, RGB888 color spanline and pixel functions */
+#define WRITE_RGBA(_x, _y, r, g, b, a) \
+ *(GLuint *)(buf + _x*3 + _y*pitch) = ((r << 16) | \
+ (g << 8) | \
+ (b << 0))
+
+#define WRITE_PIXEL(_x, _y, p) \
+ *(GLuint *)(buf + _x*3 + _y*pitch) = p
+
+#define READ_RGBA(rgba, _x, _y) \
+ do { \
+ GLuint p = *(GLuint *)(read_buf + _x*3 + _y*pitch); \
+ rgba[0] = (p >> 16) & 0xff; \
+ rgba[1] = (p >> 8) & 0xff; \
+ rgba[2] = (p >> 0) & 0xff; \
+ rgba[3] = 0xff; \
+ } while (0)
+
+#define TAG(x) r128##x##_RGB888
+#include "spantmp.h"
+
+
+
+/* 24 bit depthbuffer functions */
+#define WRITE_DEPTH(_x, _y, d) \
+ *(GLdepth *)(buf + _x*3 + _y*pitch) = d
+
+#define READ_DEPTH(d, _x, _y) \
+ d = *(GLdepth *)(buf + _x*3 + _y*pitch)
+
+#define TAG(x) r128##x##_24
+#include "depthtmp.h"
+
+
+
+/* 32 bit, ARGB8888 color spanline and pixel functions */
+#define WRITE_RGBA(_x, _y, r, g, b, a) \
+ *(GLuint *)(buf + _x*4 + _y*pitch) = ((r << 16) | \
+ (g << 8) | \
+ (b << 0) | \
+ (a << 24) )
+
+#define WRITE_PIXEL(_x, _y, p) \
+ *(GLuint *)(buf + _x*4 + _y*pitch) = p
+
+#define READ_RGBA(rgba, _x, _y) \
+ do { \
+ GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \
+ rgba[0] = (p >> 16) & 0xff; \
+ rgba[1] = (p >> 8) & 0xff; \
+ rgba[2] = (p >> 0) & 0xff; \
+ rgba[3] = (p >> 24) & 0xff; \
+ } while (0)
+
+#define TAG(x) r128##x##_ARGB8888
+#include "spantmp.h"
+
+
+
+/* 32 bit depthbuffer functions */
+#define WRITE_DEPTH(_x, _y, d) \
+ *(GLdepth *)(buf + _x*4 + _y*pitch) = d
+
+#define READ_DEPTH(d, _x, _y) \
+ d = *(GLdepth *)(buf + _x*4 + _y*pitch)
+
+#define TAG(x) r128##x##_32
+#include "depthtmp.h"
+
+
+
+void r128DDInitSpanFuncs(GLcontext *ctx)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ switch (r128ctx->r128Screen->pixel_code) {
+ case 8: /* Color Index mode not supported */
+ break;
+
+ case 15:
+ ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_ARGB1555;
+ ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_ARGB1555;
+ ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_ARGB1555;
+ ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_ARGB1555;
+ ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_ARGB1555;
+ ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_ARGB1555;
+ ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_ARGB1555;
+
+ ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_16;
+ ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_16;
+ ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_16;
+ ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_16;
+ break;
+
+ case 16:
+ ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_RGB565;
+ ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_RGB565;
+ ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_RGB565;
+ ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_RGB565;
+ ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_RGB565;
+ ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_RGB565;
+ ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_RGB565;
+
+ ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_16;
+ ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_16;
+ ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_16;
+ ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_16;
+ break;
+
+ case 24:
+ ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_RGB888;
+ ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_RGB888;
+ ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_RGB888;
+ ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_RGB888;
+ ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_RGB888;
+ ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_RGB888;
+ ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_RGB888;
+
+ ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_24;
+ ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_24;
+ ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_24;
+ ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_24;
+ break;
+
+ case 32:
+ ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_ARGB8888;
+ ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_ARGB8888;
+ ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_ARGB8888;
+ ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_ARGB8888;
+ ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_ARGB8888;
+ ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_ARGB8888;
+ ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_ARGB8888;
+
+ ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_32;
+ ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_32;
+ ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_32;
+ ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_32;
+ break;
+
+ default:
+ break;
+ }
+
+ ctx->Driver.WriteCI8Span = NULL;
+ ctx->Driver.WriteCI32Span = NULL;
+ ctx->Driver.WriteMonoCISpan = NULL;
+ ctx->Driver.WriteCI32Pixels = NULL;
+ ctx->Driver.WriteMonoCIPixels = NULL;
+ ctx->Driver.ReadCI32Span = NULL;
+ ctx->Driver.ReadCI32Pixels = NULL;
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_span.h b/xc/lib/GL/mesa/src/drv/r128/r128_span.h
new file mode 100644
index 000000000..f83a4da9f
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.h
@@ -0,0 +1,44 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Gareth Hughes <gareth@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_SPAN_H_
+#define _R128_SPAN_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void r128DDInitSpanFuncs(GLcontext *ctx);
+
+#endif
+#endif /* _R128_SPAN_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_state.c b/xc/lib/GL/mesa/src/drv/r128/r128_state.c
new file mode 100644
index 000000000..3d1ceaa24
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.c
@@ -0,0 +1,1309 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_state.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+#include "r128_tris.h"
+#include "r128_vb.h"
+#include "r128_tex.h"
+
+#include "mmath.h"
+
+#define INTERESTED (~(NEW_MODELVIEW | \
+ NEW_PROJECTION | \
+ NEW_TEXTURE_MATRIX | \
+ NEW_USER_CLIP | \
+ NEW_CLIENT_STATE | \
+ NEW_TEXTURE_ENABLE))
+
+static void r128DDUpdateState(GLcontext *ctx)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) {
+ fprintf(stderr, "r128DDUpdateState(%p)\n", ctx);
+ }
+
+ if (ctx->NewState & INTERESTED) {
+ r128ChooseRenderState(ctx);
+ r128ChooseRasterSetupFunc(ctx);
+ }
+
+ if (!r128ctx->Fallback) {
+ ctx->IndirectTriangles &= ~DD_SW_RASTERIZE;
+ ctx->IndirectTriangles |= r128ctx->IndirectTriangles;
+
+ ctx->Driver.PointsFunc = r128ctx->PointsFunc;
+ ctx->Driver.LineFunc = r128ctx->LineFunc;
+ ctx->Driver.TriangleFunc = r128ctx->TriangleFunc;
+ ctx->Driver.QuadFunc = r128ctx->QuadFunc;
+ ctx->Driver.RectFunc = NULL;
+ }
+}
+
+static void r128DDUpdateHWState(GLcontext *ctx)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ /* FIXME: state is being updated too often */
+ if (r128ctx->dirty)
+ r128UpdateHWState(r128ctx);
+}
+
+static void r128DDReducedPrimitiveChange(GLcontext *ctx, GLenum prim)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ /* FIXME: Also need to flush between tris and tristrips/fans when we
+ support them directly */
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+}
+
+static void r128DDClearColor(GLcontext *ctx,
+ GLubyte r, GLubyte g, GLubyte b, GLubyte a)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ r128ctx->ClearColor = r128PackColor(r128ctx->r128Screen->depth,
+ r, g, b, a);
+}
+
+static void r128DDColor(GLcontext *ctx,
+ GLubyte r, GLubyte g, GLubyte b, GLubyte a)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ r128ctx->Color = r128PackColor(r128ctx->r128Screen->depth, r, g, b, a);
+}
+
+static GLboolean r128DDSetDrawBuffer(GLcontext *ctx, GLenum mode)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ int x = r128ctx->driDrawable->x;
+ int y = r128ctx->driDrawable->y;
+ int found;
+
+ r128ctx->Fallback &= ~R128_FALLBACK_DRAW_BUFFER;
+
+ switch (mode) {
+ case GL_FRONT_LEFT:
+ r128ctx->drawX = r128ctx->r128Screen->fbX;
+ r128ctx->drawY = r128ctx->r128Screen->fbY;
+ found = GL_TRUE;
+ break;
+ case GL_BACK_LEFT:
+ r128ctx->drawX = r128ctx->r128Screen->backX;
+ r128ctx->drawY = r128ctx->r128Screen->backY;
+ found = GL_TRUE;
+ break;
+ default:
+ r128ctx->Fallback |= R128_FALLBACK_DRAW_BUFFER;
+ found = GL_FALSE;
+ break;
+ }
+
+ x += r128ctx->drawX;
+ y += r128ctx->drawY;
+
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) |
+ (x << R128_WINDOW_X_SHIFT));
+
+ /* Recalculate the Z buffer offset since we might be drawing to the
+ back buffer and window_xy_offset affects both color buffer and
+ depth drawing */
+ r128ctx->regs.z_offset_c = ((r128ctx->r128Screen->depthX -
+ r128ctx->drawX) *
+ (r128ctx->r128Screen->bpp/8) +
+ (r128ctx->r128Screen->depthY -
+ r128ctx->drawY) *
+ r128ctx->r128Screen->fbStride);
+
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_WIN_Z_POS;
+ return found;
+}
+
+static void r128DDSetReadBuffer(GLcontext *ctx,
+ GLframebuffer *colorBuffer,
+ GLenum mode)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ r128ctx->Fallback &= ~R128_FALLBACK_READ_BUFFER;
+
+ switch (mode) {
+ case GL_FRONT_LEFT:
+ r128ctx->readX = r128ctx->r128Screen->fbX;
+ r128ctx->readY = r128ctx->r128Screen->fbY;
+ break;
+ case GL_BACK_LEFT:
+ r128ctx->readX = r128ctx->r128Screen->backX;
+ r128ctx->readY = r128ctx->r128Screen->backY;
+ break;
+ default:
+ r128ctx->Fallback |= R128_FALLBACK_READ_BUFFER;
+ break;
+ }
+}
+
+static GLboolean r128DDColorMask(GLcontext *ctx,
+ GLboolean r, GLboolean g,
+ GLboolean b, GLboolean a)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ GLuint mask = r128PackColor(r128ctx->r128Screen->pixel_code,
+ ctx->Color.ColorMask[RCOMP],
+ ctx->Color.ColorMask[GCOMP],
+ ctx->Color.ColorMask[BCOMP],
+ ctx->Color.ColorMask[ACOMP]);
+
+ if (r128ctx->regs.plane_3d_mask_c != mask) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.plane_3d_mask_c = mask;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_MISC;
+ }
+
+ return GL_TRUE;
+}
+
+static void r128DDDither(GLcontext *ctx, GLboolean enable)
+{
+}
+
+static void r128DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ CARD32 a = r128ctx->regs.misc_3d_state_cntl_reg;
+
+ a &= ~(R128_ALPHA_TEST_MASK | R128_REF_ALPHA_MASK);
+ a |= ctx->Color.AlphaRef & R128_REF_ALPHA_MASK;
+
+ switch (func) {
+ case GL_NEVER: a |= R128_ALPHA_TEST_NEVER; break;
+ case GL_LESS: a |= R128_ALPHA_TEST_LESS; break;
+ case GL_LEQUAL: a |= R128_ALPHA_TEST_LESSEQUAL; break;
+ case GL_EQUAL: a |= R128_ALPHA_TEST_EQUAL; break;
+ case GL_GEQUAL: a |= R128_ALPHA_TEST_GREATEREQUAL; break;
+ case GL_GREATER: a |= R128_ALPHA_TEST_GREATER; break;
+ case GL_NOTEQUAL: a |= R128_ALPHA_TEST_NEQUAL; break;
+ case GL_ALWAYS: a |= R128_ALPHA_TEST_ALWAYS;
+ break;
+ default:
+ /* ERROR!!! */
+ return;
+ }
+
+ if (r128ctx->regs.misc_3d_state_cntl_reg != a) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.misc_3d_state_cntl_reg = a;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ALPHASTATE;
+ }
+}
+
+static void r128DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ CARD32 b = r128ctx->regs.misc_3d_state_cntl_reg;
+
+ b &= ~(R128_ALPHA_BLEND_SRC_MASK | R128_ALPHA_BLEND_DST_MASK);
+
+ switch (sfactor) {
+ case GL_ZERO: b |= R128_ALPHA_BLEND_SRC_ZERO;
+ break;
+ case GL_ONE: b |= R128_ALPHA_BLEND_SRC_ONE;
+ break;
+ case GL_DST_COLOR: b |= R128_ALPHA_BLEND_SRC_DESTCOLOR;
+ break;
+ case GL_ONE_MINUS_DST_COLOR: b |= R128_ALPHA_BLEND_SRC_INVDESTCOLOR;
+ break;
+ case GL_SRC_ALPHA: b |= R128_ALPHA_BLEND_SRC_SRCALPHA;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA: b |= R128_ALPHA_BLEND_SRC_INVSRCALPHA;
+ break;
+ case GL_DST_ALPHA: b |= R128_ALPHA_BLEND_SRC_DESTALPHA;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA: b |= R128_ALPHA_BLEND_SRC_INVDESTALPHA;
+ break;
+ case GL_SRC_ALPHA_SATURATE: b |= R128_ALPHA_BLEND_SRC_SRCALPHASAT;
+ break;
+#if 0
+ /* FIXME: These are not supported directly by the Rage 128.
+ They could be emulated using something like the TexEnv
+ modes. */
+ case GL_CONSTANT_COLOR: b |= 0;
+ break;
+ case GL_ONE_MINUS_CONSTANT_COLOR: b |= 0;
+ break;
+ case GL_CONSTANT_ALPHA: b |= 0;
+ break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA: b |= 0;
+ break;
+#endif
+ default:
+ /* ERROR!!! */
+ return;
+ }
+
+ switch (dfactor) {
+ case GL_ZERO: b |= R128_ALPHA_BLEND_DST_ZERO;
+ break;
+ case GL_ONE: b |= R128_ALPHA_BLEND_DST_ONE;
+ break;
+ case GL_SRC_COLOR: b |= R128_ALPHA_BLEND_DST_SRCCOLOR;
+ break;
+ case GL_ONE_MINUS_SRC_COLOR: b |= R128_ALPHA_BLEND_DST_INVSRCCOLOR;
+ break;
+ case GL_SRC_ALPHA: b |= R128_ALPHA_BLEND_DST_SRCALPHA;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA: b |= R128_ALPHA_BLEND_DST_INVSRCALPHA;
+ break;
+ case GL_DST_ALPHA: b |= R128_ALPHA_BLEND_DST_DESTALPHA;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA: b |= R128_ALPHA_BLEND_DST_INVDESTALPHA;
+ break;
+#if 0
+ /* FIXME: These are not supported directly by the Rage 128.
+ They could be emulated using something like the TexEnv
+ modes. */
+ case GL_CONSTANT_COLOR: b |= 0;
+ break;
+ case GL_ONE_MINUS_CONSTANT_COLOR: b |= 0;
+ break;
+ case GL_CONSTANT_ALPHA: b |= 0;
+ break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA: b |= 0;
+ break;
+#endif
+ default:
+ /* ERROR!!! */
+ return;
+ }
+
+ if (r128ctx->regs.misc_3d_state_cntl_reg != b) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.misc_3d_state_cntl_reg = b;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ALPHASTATE;
+ }
+}
+
+static void r128DDBlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB,
+ GLenum dfactorRGB, GLenum sfactorA,
+ GLenum dfactorA)
+{
+ if (sfactorRGB != sfactorA || dfactorRGB != dfactorA) {
+ /* ERROR!!! */
+ return;
+ }
+
+ r128DDBlendFunc(ctx, sfactorRGB, dfactorRGB);
+}
+
+static void r128DDClearDepth(GLcontext *ctx, GLclampd d)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ switch (r128ctx->regs.z_sten_cntl_c & R128_Z_PIX_WIDTH_MASK) {
+ case R128_Z_PIX_WIDTH_16: r128ctx->ClearDepth = d * 0x0000ffff; break;
+ case R128_Z_PIX_WIDTH_24: r128ctx->ClearDepth = d * 0x00ffffff; break;
+ case R128_Z_PIX_WIDTH_32: r128ctx->ClearDepth = d * 0xffffffff; break;
+ default: return;
+ }
+}
+
+static void r128DDCullFace(GLcontext *ctx, GLenum mode)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ CARD32 f = r128ctx->regs.pm4_vc_fpu_setup;
+
+ if (!ctx->Polygon.CullFlag) return;
+
+ f &= ~(R128_BACKFACE_MASK | R128_FRONTFACE_MASK);
+
+ switch (mode) {
+ case GL_FRONT: f |= R128_BACKFACE_SOLID; break;
+ case GL_BACK: f |= R128_FRONTFACE_SOLID; break;
+ case GL_FRONT_AND_BACK: break;
+ default: return;
+ }
+
+ if (r128ctx->regs.pm4_vc_fpu_setup != f) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.pm4_vc_fpu_setup = f;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_SETUPSTATE;
+ }
+}
+
+static void r128DDFrontFace(GLcontext *ctx, GLenum mode)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ CARD32 f = r128ctx->regs.pm4_vc_fpu_setup;
+
+ f &= ~R128_FRONT_DIR_MASK;
+
+ switch (mode) {
+ case GL_CW: f |= R128_FRONT_DIR_CW; break;
+ case GL_CCW: f |= R128_FRONT_DIR_CCW; break;
+ default: return;
+ }
+
+ if (r128ctx->regs.pm4_vc_fpu_setup != f) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.pm4_vc_fpu_setup = f;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_SETUPSTATE;
+ }
+}
+
+static void r128DDDepthFunc(GLcontext *ctx, GLenum func)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ CARD32 z = r128ctx->regs.z_sten_cntl_c;
+
+ z &= ~R128_Z_TEST_MASK;
+
+ switch (func) {
+ case GL_NEVER: z |= R128_Z_TEST_NEVER; break;
+ case GL_LESS: z |= R128_Z_TEST_LESS; break;
+ case GL_LEQUAL: z |= R128_Z_TEST_LESSEQUAL; break;
+ case GL_EQUAL: z |= R128_Z_TEST_EQUAL; break;
+ case GL_GEQUAL: z |= R128_Z_TEST_GREATEREQUAL; break;
+ case GL_GREATER: z |= R128_Z_TEST_GREATER; break;
+ case GL_NOTEQUAL: z |= R128_Z_TEST_NEQUAL; break;
+ case GL_ALWAYS: z |= R128_Z_TEST_ALWAYS; break;
+ default: return;
+ }
+
+ if (r128ctx->regs.z_sten_cntl_c != z) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.z_sten_cntl_c = z;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ZSTENSTATE;
+ }
+}
+
+static void r128DDDepthMask(GLcontext *ctx, GLboolean flag)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ CARD32 t = r128ctx->regs.tex_cntl_c;
+
+ if (flag) t |= R128_Z_WRITE_ENABLE;
+ else t &= ~R128_Z_WRITE_ENABLE;
+
+ if (r128ctx->regs.tex_cntl_c != t) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.tex_cntl_c = t;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ENGINESTATE;
+ }
+}
+
+static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ CARD32 t = r128ctx->regs.tex_cntl_c;
+ CARD32 f = r128ctx->regs.pm4_vc_fpu_setup;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) {
+ fprintf(stderr, "r128DDEnable( %p, 0x%x = %s )\n",
+ ctx, cap, state ? "GL_TRUE" : "GL_FALSE");
+ }
+
+ switch (cap) {
+ case GL_ALPHA_TEST:
+ if (state) t |= R128_ALPHA_TEST_ENABLE;
+ else t &= ~R128_ALPHA_TEST_ENABLE;
+ break;
+
+ case GL_AUTO_NORMAL: return;
+
+ case GL_BLEND:
+ if (state) t |= R128_ALPHA_ENABLE;
+ else t &= ~R128_ALPHA_ENABLE;
+ break;
+
+ case GL_CLIP_PLANE0:
+ case GL_CLIP_PLANE1:
+ case GL_CLIP_PLANE2:
+ case GL_CLIP_PLANE3:
+ case GL_CLIP_PLANE4:
+ case GL_CLIP_PLANE5:
+ case GL_COLOR_MATERIAL: return;
+
+ case GL_CULL_FACE:
+ f &= ~(R128_BACKFACE_MASK | R128_FRONTFACE_MASK);
+ if (state) {
+ switch (ctx->Polygon.CullFaceMode) {
+ case GL_FRONT: f |= R128_BACKFACE_SOLID; break;
+ case GL_BACK: f |= R128_FRONTFACE_SOLID; break;
+ case GL_FRONT_AND_BACK: break;
+ default: return;
+ }
+ } else {
+ f |= R128_BACKFACE_SOLID | R128_FRONTFACE_SOLID;
+ }
+ break;
+
+ case GL_DEPTH_TEST:
+ if (state) t |= R128_Z_ENABLE;
+ else t &= ~R128_Z_ENABLE;
+ break;
+
+ case GL_DITHER:
+ if (state) t |= R128_DITHER_ENABLE;
+ else t &= ~R128_DITHER_ENABLE;
+ break;
+
+ case GL_FOG:
+ if (state) t |= R128_FOG_ENABLE;
+ else t &= ~R128_FOG_ENABLE;
+ break;
+
+ case GL_LIGHT0:
+ case GL_LIGHT1:
+ case GL_LIGHT2:
+ case GL_LIGHT3:
+ case GL_LIGHT4:
+ case GL_LIGHT5:
+ case GL_LIGHT6:
+ case GL_LIGHT7:
+ case GL_LIGHTING:
+ case GL_LINE_SMOOTH:
+ case GL_LINE_STIPPLE:
+ case GL_INDEX_LOGIC_OP:
+ case GL_COLOR_LOGIC_OP:
+ case GL_MAP1_COLOR_4:
+ case GL_MAP1_INDEX:
+ case GL_MAP1_NORMAL:
+ case GL_MAP1_TEXTURE_COORD_1:
+ case GL_MAP1_TEXTURE_COORD_2:
+ case GL_MAP1_TEXTURE_COORD_3:
+ case GL_MAP1_TEXTURE_COORD_4:
+ case GL_MAP1_VERTEX_3:
+ case GL_MAP1_VERTEX_4:
+ case GL_MAP2_COLOR_4:
+ case GL_MAP2_INDEX:
+ case GL_MAP2_NORMAL:
+ case GL_MAP2_TEXTURE_COORD_1:
+ case GL_MAP2_TEXTURE_COORD_2:
+ case GL_MAP2_TEXTURE_COORD_3:
+ case GL_MAP2_TEXTURE_COORD_4:
+ case GL_MAP2_VERTEX_3:
+ case GL_MAP2_VERTEX_4:
+ case GL_NORMALIZE:
+ case GL_POINT_SMOOTH:
+ case GL_POLYGON_SMOOTH:
+ case GL_POLYGON_STIPPLE:
+ case GL_POLYGON_OFFSET_POINT:
+ case GL_POLYGON_OFFSET_LINE:
+ case GL_POLYGON_OFFSET_FILL:
+ case GL_RESCALE_NORMAL_EXT: return;
+
+ case GL_SCISSOR_TEST:
+ /* FIXME: Hook up the software scissor */
+#if 0
+ r128ctx->Scissor = state;
+#endif
+ break;
+
+ case GL_SHARED_TEXTURE_PALETTE_EXT:
+ case GL_STENCIL_TEST: return;
+
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ /* This is handled in r128UpdateTex[01]State() */
+ r128ctx->dirty |= R128_UPDATE_TEXSTATE;
+ break;
+
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_GEN_Q:
+ case GL_TEXTURE_GEN_R:
+ case GL_TEXTURE_GEN_S:
+ case GL_TEXTURE_GEN_T: return;
+
+ /* Client state */
+ case GL_VERTEX_ARRAY:
+ case GL_NORMAL_ARRAY:
+ case GL_COLOR_ARRAY:
+ case GL_INDEX_ARRAY:
+ case GL_TEXTURE_COORD_ARRAY:
+ case GL_EDGE_FLAG_ARRAY: return;
+
+ default: return;
+ }
+
+ if (r128ctx->regs.tex_cntl_c != t) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.tex_cntl_c = t;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ENGINESTATE;
+ }
+ if (r128ctx->regs.pm4_vc_fpu_setup != f) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.pm4_vc_fpu_setup = f;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_SETUPSTATE;
+ }
+
+}
+
+static void r128DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ GLubyte c[4];
+ CARD32 col;
+ floatTOint fog;
+ GLenum mode;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) {
+ fprintf(stderr, "r128DDFogfv(%p, 0x%x)\n", ctx, pname);
+ }
+
+ switch (pname) {
+ case GL_FOG_MODE:
+ mode = (GLenum)(GLint)*param;
+ if (r128ctx->FogMode != mode) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->FogMode = mode;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_FOGTABLE;
+ }
+ break;
+
+ case GL_FOG_DENSITY:
+ fog.f = *param;
+ if (r128ctx->regs.fog_3d_table_density != fog.i) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.fog_3d_table_density = fog.i;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_FOGSTATE;
+ }
+ break;
+
+ case GL_FOG_START:
+ fog.f = *param;
+ if (r128ctx->regs.fog_3d_table_start != fog.i) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.fog_3d_table_start = fog.i;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_FOGSTATE;
+ }
+ break;
+
+ case GL_FOG_END:
+ fog.f = *param;
+ if (r128ctx->regs.fog_3d_table_end != fog.i) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.fog_3d_table_end = fog.i;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_FOGSTATE;
+ }
+ break;
+
+ case GL_FOG_COLOR:
+ FLOAT_RGBA_TO_UBYTE_RGBA(c, ctx->Fog.Color);
+ col = r128PackColor(32, c[0], c[1], c[2], c[3]);
+ if (r128ctx->regs.fog_color_c != col) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.fog_color_c = col;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_FOGSTATE;
+ }
+ break;
+
+ default:
+ return;
+ }
+}
+
+static void r128DDScissor(GLcontext *ctx,
+ GLint x, GLint y, GLsizei w, GLsizei h)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ r128ctx->ScissorRect.x1 = x;
+ r128ctx->ScissorRect.y1 = r128ctx->driDrawable->h - (y + h);
+ r128ctx->ScissorRect.x2 = x + w;
+ r128ctx->ScissorRect.y2 = r128ctx->driDrawable->h - y;
+}
+
+/* Initialize the driver's state functions */
+void r128DDInitStateFuncs(GLcontext *ctx)
+{
+ ctx->Driver.UpdateState = r128DDUpdateState;
+
+ ctx->Driver.ClearIndex = NULL;
+ ctx->Driver.ClearColor = r128DDClearColor;
+ ctx->Driver.Index = NULL;
+ ctx->Driver.Color = r128DDColor;
+ ctx->Driver.SetDrawBuffer = r128DDSetDrawBuffer;
+ ctx->Driver.SetReadBuffer = r128DDSetReadBuffer;
+
+ ctx->Driver.IndexMask = NULL;
+ ctx->Driver.ColorMask = r128DDColorMask;
+ ctx->Driver.LogicOp = NULL;
+ ctx->Driver.Dither = r128DDDither;
+
+ ctx->Driver.NearFar = NULL;
+
+ ctx->Driver.RenderStart = r128DDUpdateHWState;
+ ctx->Driver.RenderFinish = NULL;
+ ctx->Driver.RasterSetup = NULL;
+
+ ctx->Driver.RenderVBClippedTab = NULL;
+ ctx->Driver.RenderVBCulledTab = NULL;
+ ctx->Driver.RenderVBRawTab = NULL;
+
+ ctx->Driver.ReducedPrimitiveChange = r128DDReducedPrimitiveChange;
+ ctx->Driver.MultipassFunc = NULL;
+
+ ctx->Driver.AlphaFunc = r128DDAlphaFunc;
+ ctx->Driver.BlendEquation = NULL;
+ ctx->Driver.BlendFunc = r128DDBlendFunc;
+ ctx->Driver.BlendFuncSeparate = r128DDBlendFuncSeparate;
+ ctx->Driver.ClearDepth = r128DDClearDepth;
+ ctx->Driver.CullFace = r128DDCullFace;
+ ctx->Driver.FrontFace = r128DDFrontFace;
+ ctx->Driver.DepthFunc = r128DDDepthFunc;
+ ctx->Driver.DepthMask = r128DDDepthMask;
+ ctx->Driver.DepthRange = NULL;
+ ctx->Driver.Enable = r128DDEnable;
+ ctx->Driver.Fogfv = r128DDFogfv;
+ ctx->Driver.Hint = NULL;
+ ctx->Driver.Lightfv = NULL;
+ ctx->Driver.LightModelfv = NULL;
+ ctx->Driver.PolygonMode = NULL;
+ ctx->Driver.Scissor = r128DDScissor;
+ ctx->Driver.ShadeModel = NULL;
+ ctx->Driver.ClearStencil = NULL;
+ ctx->Driver.StencilFunc = NULL;
+ ctx->Driver.StencilMask = NULL;
+ ctx->Driver.StencilOp = NULL;
+ ctx->Driver.Viewport = NULL;
+}
+
+/* Initialize the context's hardware state */
+void r128DDInitState(r128ContextPtr r128ctx)
+{
+ int dst_bpp, depth_bpp, pitch, i;
+ CARD32 depthClear;
+
+ pitch = r128ctx->r128Screen->fbStride / r128ctx->r128Screen->bpp;
+
+ switch (r128ctx->r128Screen->pixel_code) {
+ case 8: dst_bpp = R128_GMC_DST_8BPP_CI; break;
+ case 15: dst_bpp = R128_GMC_DST_15BPP; break;
+ case 16: dst_bpp = R128_GMC_DST_16BPP; break;
+ case 24: dst_bpp = R128_GMC_DST_24BPP; break;
+ case 32: dst_bpp = R128_GMC_DST_32BPP; break;
+ default:
+ fprintf(stderr, "Error: Unsupported pixel depth %d... exiting\n",
+ r128ctx->r128Screen->pixel_code);
+ exit(-1);
+ }
+
+ /* FIXME: Figure out how to use 16bpp depth buffer in 32bpp mode */
+ switch (r128ctx->glCtx->Visual->DepthBits) {
+ case 16: depthClear = 0x0000ffff; depth_bpp = R128_Z_PIX_WIDTH_16; break;
+ case 24: depthClear = 0x00ffffff; depth_bpp = R128_Z_PIX_WIDTH_24; break;
+ case 32: depthClear = 0xffffffff; depth_bpp = R128_Z_PIX_WIDTH_32; break;
+ default:
+ fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
+ r128ctx->r128Screen->bpp);
+ exit(-1);
+ break;
+ }
+
+ r128ctx->dirty = R128_ALL_DIRTY;
+ r128ctx->dirty_context = R128_CTX_ALL_DIRTY;
+
+ r128ctx->RenderIndex = R128_FALLBACK_BIT;
+ r128ctx->PointsFunc = NULL;
+ r128ctx->LineFunc = NULL;
+ r128ctx->TriangleFunc = NULL;
+ r128ctx->QuadFunc = NULL;
+
+ r128ctx->IndirectTriangles = 0;
+ r128ctx->Fallback = 0;
+
+ if (r128ctx->glCtx->Visual->DBflag) {
+ r128ctx->drawX = r128ctx->r128Screen->backX;
+ r128ctx->drawY = r128ctx->r128Screen->backY;
+ r128ctx->readX = r128ctx->r128Screen->backX;
+ r128ctx->readY = r128ctx->r128Screen->backY;
+ } else {
+ r128ctx->drawX = r128ctx->r128Screen->fbX;
+ r128ctx->drawY = r128ctx->r128Screen->fbY;
+ r128ctx->readX = r128ctx->r128Screen->fbX;
+ r128ctx->readY = r128ctx->r128Screen->fbY;
+ }
+
+ r128ctx->ClearColor = 0x00000000;
+ r128ctx->ClearDepth = depthClear;
+
+ r128ctx->regs.scale_3d_cntl =
+ R128_SCALE_DITHER_TABLE |
+ R128_TEX_CACHE_SIZE_FULL |
+ R128_DITHER_INIT_RESET |
+ R128_SCALE_3D_TEXMAP_SHADE |
+ R128_SCALE_PIX_REPLICATE |
+ /* R128_TEX_CACHE_SPLIT | */
+ R128_ALPHA_COMB_ADD_CLAMP |
+ R128_FOG_TABLE |
+ R128_ALPHA_BLEND_SRC_ONE |
+ R128_ALPHA_BLEND_DST_ZERO |
+ R128_ALPHA_TEST_ALWAYS |
+ R128_COMPOSITE_SHADOW_CMP_EQUAL |
+ R128_TEX_MAP_ALPHA_IN_TEXTURE |
+ R128_TEX_CACHE_LINE_SIZE_8QW;
+
+ r128ctx->regs.dst_pitch_offset_c = pitch << R128_PITCH_SHIFT;
+
+ r128ctx->regs.dp_gui_master_cntl =
+ R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_DST_CLIPPING |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ dst_bpp |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_GMC_BYTE_MSB_TO_LSB |
+ R128_GMC_CONVERSION_TEMP_6500 |
+ R128_ROP3_S |
+ R128_DP_SRC_SOURCE_MEMORY |
+ R128_GMC_3D_FCN_EN |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_AUX_CLIP_DIS |
+ R128_GMC_WR_MSK_DIS;
+
+ r128ctx->regs.sc_top_left_c = 0x00000000;
+ r128ctx->regs.sc_bottom_right_c = 0x1fff1fff;
+
+ r128ctx->regs.aux_sc_cntl = 0x00000000;
+
+ r128ctx->regs.aux1_sc_left = 0x00000000;
+ r128ctx->regs.aux1_sc_right = 0x00001fff;
+ r128ctx->regs.aux1_sc_top = 0x00000000;
+ r128ctx->regs.aux1_sc_bottom = 0x00001fff;
+
+ r128ctx->regs.aux2_sc_left = 0x00000000;
+ r128ctx->regs.aux2_sc_right = 0x00001fff;
+ r128ctx->regs.aux2_sc_top = 0x00000000;
+ r128ctx->regs.aux2_sc_bottom = 0x00001fff;
+
+ r128ctx->regs.aux3_sc_left = 0x00000000;
+ r128ctx->regs.aux3_sc_right = 0x00001fff;
+ r128ctx->regs.aux3_sc_top = 0x00000000;
+ r128ctx->regs.aux3_sc_bottom = 0x00001fff;
+
+ r128ctx->regs.z_offset_c = (r128ctx->r128Screen->depthX *
+ (r128ctx->r128Screen->bpp/8) +
+ r128ctx->r128Screen->depthY *
+ r128ctx->r128Screen->fbStride);
+ r128ctx->regs.z_pitch_c = pitch;
+
+ r128ctx->regs.z_sten_cntl_c =
+ depth_bpp |
+ R128_Z_TEST_LESS |
+ R128_STENCIL_TEST_ALWAYS |
+ R128_STENCIL_S_FAIL_KEEP |
+ R128_STENCIL_ZPASS_KEEP |
+ R128_STENCIL_ZFAIL_KEEP;
+
+ r128ctx->regs.tex_cntl_c =
+ R128_Z_WRITE_ENABLE |
+ R128_SHADE_ENABLE |
+ R128_DITHER_ENABLE |
+ R128_ALPHA_IN_TEX_COMPLETE_A |
+ R128_LIGHT_DIS |
+ R128_ALPHA_LIGHT_DIS |
+ R128_TEX_CACHE_FLUSH |
+ (0x0f << R128_LOD_BIAS_SHIFT);
+
+ r128ctx->regs.misc_3d_state_cntl_reg =
+ R128_MISC_SCALE_3D_TEXMAP_SHADE |
+ R128_MISC_SCALE_PIX_REPLICATE |
+ R128_ALPHA_COMB_ADD_CLAMP |
+ R128_FOG_TABLE |
+ R128_ALPHA_BLEND_SRC_ONE |
+ R128_ALPHA_BLEND_DST_ZERO |
+ R128_ALPHA_TEST_ALWAYS;
+
+ r128ctx->regs.texture_clr_cmp_clr_c = 0x00000000;
+ r128ctx->regs.texture_clr_cmp_msk_c = 0xffffffff;
+
+ r128ctx->regs.prim_tex_cntl_c =
+ R128_MIN_BLEND_NEAREST |
+ R128_MAG_BLEND_NEAREST |
+ R128_MIP_MAP_DISABLE |
+ R128_TEX_CLAMP_S_WRAP |
+ R128_TEX_CLAMP_T_WRAP;
+
+ r128ctx->regs.prim_texture_combine_cntl_c =
+ R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA;
+
+ r128ctx->regs.tex_size_pitch_c =
+ (0 << R128_TEX_PITCH_SHIFT) |
+ (0 << R128_TEX_SIZE_SHIFT) |
+ (0 << R128_TEX_HEIGHT_SHIFT) |
+ (0 << R128_TEX_MIN_SIZE_SHIFT) |
+ (0 << R128_SEC_TEX_PITCH_SHIFT) |
+ (0 << R128_SEC_TEX_SIZE_SHIFT) |
+ (0 << R128_SEC_TEX_HEIGHT_SHIFT) |
+ (0 << R128_SEC_TEX_MIN_SIZE_SHIFT);
+
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.prim_tex_offset[i] = 0x00000000;
+
+ r128ctx->regs.sec_tex_cntl_c =
+ R128_SEC_SELECT_PRIM_ST;
+
+ r128ctx->regs.sec_tex_combine_cntl_c =
+ R128_COMB_DIS |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_DIS |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA;
+
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.sec_tex_offset[i] = 0x00000000;
+
+ r128ctx->regs.constant_color_c = 0x00ffffff;
+ r128ctx->regs.prim_texture_border_color_c = 0x00ffffff;
+ r128ctx->regs.sec_texture_border_color_c = 0x00ffffff;
+ r128ctx->regs.sten_ref_mask_c = 0xffff0000;
+ r128ctx->regs.plane_3d_mask_c = 0xffffffff;
+
+ r128ctx->regs.setup_cntl =
+ R128_COLOR_GOURAUD |
+ R128_PRIM_TYPE_TRI |
+#if 1
+ /* FIXME: Let r128 multiply? */
+ R128_TEXTURE_ST_MULT_W |
+#else
+ /* FIXME: Or, pre multiply? */
+ R128_TEXTURE_ST_DIRECT |
+#endif
+ R128_STARTING_VERTEX_1 |
+ R128_ENDING_VERTEX_3 |
+ R128_SU_POLY_LINE_NOT_LAST |
+ R128_SUB_PIX_4BITS;
+
+ r128ctx->regs.pm4_vc_fpu_setup =
+ R128_FRONT_DIR_CCW |
+ R128_BACKFACE_SOLID |
+ R128_FRONTFACE_SOLID |
+ R128_FPU_COLOR_GOURAUD |
+ R128_FPU_SUB_PIX_4BITS |
+ R128_FPU_MODE_3D |
+ R128_TRAP_BITS_DISABLE |
+ R128_XFACTOR_2 |
+ R128_YFACTOR_2 |
+ R128_FLAT_SHADE_VERTEX_OGL |
+ R128_FPU_ROUND_TRUNCATE |
+ R128_WM_SEL_8DW;
+
+ r128ctx->FogMode = GL_EXP;
+ r128ctx->regs.fog_color_c = 0x00808080;
+ r128ctx->regs.fog_3d_table_start = 0x00000000;
+ r128ctx->regs.fog_3d_table_end = 0xffffffff;
+ r128ctx->regs.fog_3d_table_density = 0x00000000;
+
+ r128ctx->regs.window_xy_offset = 0x00000000;
+
+ r128ctx->regs.dp_write_mask = 0xffffffff;
+
+ r128ctx->regs.pc_gui_ctlstat = R128_PC_FLUSH_GUI;
+
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ALL_DIRTY;
+}
+
+/* Upload the fog table for the current fog mode */
+static void r128UploadFogTable(r128ContextPtr r128ctx)
+{
+ int i;
+
+ R128CCE0(R128_CCE_PACKET0, R128_FOG_TABLE_INDEX, 0);
+ R128CCE(0x00000000);
+
+ R128CCE0(R128_CCE_PACKET0_ONE_REG_WR, R128_FOG_TABLE_DATA, 255);
+
+ switch (r128ctx->FogMode) {
+ case GL_LINEAR:
+ for (i = 0; i < 256; i++) {
+ R128CCE(255 - i);
+ }
+ break;
+ case GL_EXP:
+ for (i = 0; i < 256; i++) {
+ R128CCE(255 - FLOAT_TO_UBYTE(exp(i - 255)));
+ }
+ break;
+ case GL_EXP2:
+ for (i = 0; i < 256; i++) {
+ R128CCE(255 - FLOAT_TO_UBYTE(exp((i - 255) * (i - 255))));
+ }
+ break;
+ }
+}
+
+/* Load the current context's state into the hardware */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128LoadContext(r128ContextPtr r128ctx)
+{
+ int i;
+ int tex_size_pitch_done = GL_FALSE;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) {
+ fprintf(stderr, "r128LoadContext(%p)\n", r128ctx->glCtx);
+ }
+
+#if 0
+ r128ctx->dirty_context = R128_CTX_ALL_DIRTY;
+#endif
+
+#if 1
+ /* FIXME: Why do these need to be updated even when they don't change? */
+ r128ctx->dirty_context |= (R128_CTX_MISC |
+ R128_CTX_ENGINESTATE |
+ R128_CTX_ALPHASTATE);
+#endif
+
+#if 1
+ /* FIXME: Is this _really_ needed? */
+ if (r128ctx->dirty_context)
+ if (!R128CCE_USE_RING_BUFFER(r128ctx->r128Screen->CCEMode))
+ R128CCE_WAIT_FOR_IDLE(r128ctx);
+#endif
+
+ if (r128ctx->dirty_context & R128_CTX_MISC) {
+ R128CCE1(R128_CCE_PACKET1, R128_SCALE_3D_CNTL, R128_DP_WRITE_MASK);
+ R128CCE(r128ctx->regs.scale_3d_cntl);
+ R128CCE(r128ctx->regs.dp_write_mask);
+
+ R128CCE0(R128_CCE_PACKET0, R128_DST_PITCH_OFFSET_C, 1);
+ R128CCE(r128ctx->regs.dst_pitch_offset_c);
+ R128CCE(r128ctx->regs.dp_gui_master_cntl);
+
+ R128CCE0(R128_CCE_PACKET0, R128_TEXTURE_CLR_CMP_CLR_C, 1);
+ R128CCE(r128ctx->regs.texture_clr_cmp_clr_c);
+ R128CCE(r128ctx->regs.texture_clr_cmp_msk_c);
+
+ R128CCE0(R128_CCE_PACKET0, R128_STEN_REF_MASK_C, 1);
+ R128CCE(r128ctx->regs.sten_ref_mask_c);
+ R128CCE(r128ctx->regs.plane_3d_mask_c);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_ENGINESTATE) {
+ R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0);
+ R128CCE(r128ctx->regs.tex_cntl_c);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_TEX0STATE) {
+ R128CCE0(R128_CCE_PACKET0, R128_PRIM_TEX_CNTL_C, 2+R128_TEX_MAXLEVELS);
+ R128CCE(r128ctx->regs.prim_tex_cntl_c);
+ R128CCE(r128ctx->regs.prim_texture_combine_cntl_c);
+ R128CCE(r128ctx->regs.tex_size_pitch_c);
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ R128CCE(r128ctx->regs.prim_tex_offset[i]);
+
+ R128CCE0(R128_CCE_PACKET0, R128_PRIM_TEXTURE_BORDER_COLOR_C, 0);
+ R128CCE(r128ctx->regs.prim_texture_border_color_c);
+
+ tex_size_pitch_done = GL_TRUE;
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_TEX1STATE) {
+ if (!tex_size_pitch_done) {
+ R128CCE0(R128_CCE_PACKET0, R128_TEX_SIZE_PITCH_C, 0);
+ R128CCE(r128ctx->regs.tex_size_pitch_c);
+ }
+
+ R128CCE0(R128_CCE_PACKET0, R128_SEC_TEX_CNTL_C, 1+R128_TEX_MAXLEVELS);
+ R128CCE(r128ctx->regs.sec_tex_cntl_c);
+ R128CCE(r128ctx->regs.sec_tex_combine_cntl_c);
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ R128CCE(r128ctx->regs.sec_tex_offset[i]);
+
+ R128CCE0(R128_CCE_PACKET0, R128_SEC_TEXTURE_BORDER_COLOR_C, 0);
+ R128CCE(r128ctx->regs.sec_texture_border_color_c);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_TEXENVSTATE) {
+ R128CCE0(R128_CCE_PACKET0, R128_CONSTANT_COLOR_C, 0);
+ R128CCE(r128ctx->regs.constant_color_c);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_FOGSTATE) {
+ R128CCE0(R128_CCE_PACKET0, R128_FOG_3D_TABLE_START, 1);
+ R128CCE(r128ctx->regs.fog_3d_table_start);
+ R128CCE(r128ctx->regs.fog_3d_table_end);
+
+ R128CCE1(R128_CCE_PACKET1,
+ R128_FOG_COLOR_C, R128_FOG_3D_TABLE_DENSITY);
+ R128CCE(r128ctx->regs.fog_color_c);
+ R128CCE(r128ctx->regs.fog_3d_table_density);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_FOGTABLE) {
+ r128UploadFogTable(r128ctx);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_ZSTENSTATE) {
+ R128CCE0(R128_CCE_PACKET0, R128_Z_STEN_CNTL_C, 0);
+ R128CCE(r128ctx->regs.z_sten_cntl_c);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_SCISSORS) {
+ R128CCE0(R128_CCE_PACKET0, R128_SC_TOP_LEFT_C, 1);
+ R128CCE(r128ctx->regs.sc_top_left_c);
+ R128CCE(r128ctx->regs.sc_bottom_right_c);
+ }
+
+ if (r128ctx->dirty_context & (R128_CTX_ALPHASTATE |
+ R128_CTX_FOGSTATE)) {
+ R128CCE0(R128_CCE_PACKET0, R128_MISC_3D_STATE_CNTL_REG, 0);
+ R128CCE(r128ctx->regs.misc_3d_state_cntl_reg);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_SETUPSTATE) {
+ R128CCE1(R128_CCE_PACKET1, R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP);
+ R128CCE(r128ctx->regs.setup_cntl);
+ R128CCE(r128ctx->regs.pm4_vc_fpu_setup);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_WIN_Z_POS) {
+ R128CCE0(R128_CCE_PACKET0, R128_WINDOW_XY_OFFSET, 0);
+ R128CCE(r128ctx->regs.window_xy_offset);
+
+ R128CCE0(R128_CCE_PACKET0, R128_Z_OFFSET_C, 1);
+ R128CCE(r128ctx->regs.z_offset_c);
+ R128CCE(r128ctx->regs.z_pitch_c);
+ }
+
+#if 0
+ if (r128ctx->dirty_context & R128_CTX_FLUSH_PIX_CACHE) {
+ R128CCE0(R128_CCE_PACKET0, R128_PC_GUI_CTLSTAT, 0);
+ R128CCE(r128ctx->regs.pc_gui_ctlstat);
+ }
+#endif
+
+ R128CCE_SUBMIT_PACKETS();
+
+ /* Turn off the texture cache flushing */
+ r128ctx->regs.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH;
+
+ /* Turn off the pixel cache flushing */
+ r128ctx->regs.pc_gui_ctlstat &= ~R128_PC_FLUSH_ALL;
+
+ r128ctx->dirty_context = R128_CTX_CLEAN;
+}
+
+/* Set the hardware clip rects for drawing to the current color buffer */
+/* NOTE: This function is only called while holding the hardware lock */
+void r128SetClipRects(r128ContextPtr r128ctx,
+ XF86DRIClipRectPtr pc, int nc)
+{
+ if (!pc) return;
+
+ /* Clear any previous auxiliary scissors */
+ r128ctx->regs.aux_sc_cntl = 0x00000000;
+
+ switch (nc) {
+ case 3:
+ R128CCE0(R128_CCE_PACKET0, R128_AUX3_SC_LEFT, 3);
+ R128CCE(pc[2].x1 + r128ctx->drawX);
+ R128CCE(pc[2].x2-1 + r128ctx->drawX);
+ R128CCE(pc[2].y1 + r128ctx->drawY);
+ R128CCE(pc[2].y2-1 + r128ctx->drawY);
+
+ r128ctx->regs.aux_sc_cntl |= R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR;
+
+ case 2:
+ R128CCE0(R128_CCE_PACKET0, R128_AUX2_SC_LEFT, 3);
+ R128CCE(pc[1].x1 + r128ctx->drawX);
+ R128CCE(pc[1].x2-1 + r128ctx->drawX);
+ R128CCE(pc[1].y1 + r128ctx->drawY);
+ R128CCE(pc[1].y2-1 + r128ctx->drawY);
+
+ r128ctx->regs.aux_sc_cntl |= R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR;
+
+ case 1:
+ R128CCE0(R128_CCE_PACKET0, R128_AUX1_SC_LEFT, 3);
+ R128CCE(pc[0].x1 + r128ctx->drawX);
+ R128CCE(pc[0].x2-1 + r128ctx->drawX);
+ R128CCE(pc[0].y1 + r128ctx->drawY);
+ R128CCE(pc[0].y2-1 + r128ctx->drawY);
+
+ r128ctx->regs.aux_sc_cntl |= R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR;
+ break;
+
+ default:
+ return;
+ }
+
+ R128CCE0(R128_CCE_PACKET0, R128_AUX_SC_CNTL, 0);
+ R128CCE(r128ctx->regs.aux_sc_cntl);
+
+ R128CCE_SUBMIT_PACKETS();
+}
+
+/* Update the driver's notion of the window position */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128UpdateWindowPosition(r128ContextPtr r128ctx)
+{
+ int x = r128ctx->driDrawable->x + r128ctx->drawX;
+ int y = r128ctx->driDrawable->y + r128ctx->drawY;
+
+#if 0
+ /* FIXME: Is this _really_ needed? */
+ R128CCE_FLUSH_VB(r128ctx);
+#endif
+ r128ctx->regs.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) |
+ (x << R128_WINDOW_X_SHIFT));
+
+ /* Recalculate the Z buffer offset since we might be drawing to the
+ back buffer and window_xy_offset affects both color buffer and
+ depth drawing */
+ r128ctx->regs.z_offset_c = ((r128ctx->r128Screen->depthX -
+ r128ctx->drawX) *
+ (r128ctx->r128Screen->bpp/8) +
+ (r128ctx->r128Screen->depthY -
+ r128ctx->drawY) *
+ r128ctx->r128Screen->fbStride);
+
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_WIN_Z_POS;
+}
+
+/* Update the hardware state */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128UpdateHWStateLocked(r128ContextPtr r128ctx)
+{
+ if (r128ctx->dirty & R128_REQUIRE_QUIESCENCE)
+ R128CCE_WAIT_FOR_IDLE(r128ctx);
+
+ /* Update any state that might have changed recently */
+
+ /* Update the clip rects */
+ if (r128ctx->dirty & R128_UPDATE_WINPOS)
+ r128UpdateWindowPosition(r128ctx);
+
+ /* Update texture state and then upload the images */
+ /* Note: Texture images can only be updated after the state has been set */
+ if (r128ctx->dirty & R128_UPDATE_TEXSTATE)
+ r128UpdateTextureState(r128ctx);
+ if (r128ctx->dirty & R128_UPDATE_TEX0IMAGES)
+ r128UploadTexImages(r128ctx, r128ctx->CurrentTexObj[0]);
+ if (r128ctx->dirty & R128_UPDATE_TEX1IMAGES)
+ r128UploadTexImages(r128ctx, r128ctx->CurrentTexObj[1]);
+
+ /* Load the state into the hardware */
+ /* Note: This must be done after all other state has been set */
+ if (r128ctx->dirty & R128_UPDATE_CONTEXT)
+ r128LoadContext(r128ctx);
+
+ r128ctx->dirty = R128_CLEAN;
+}
+
+/* Update the hardware state */
+void r128UpdateHWState(r128ContextPtr r128ctx)
+{
+ LOCK_HARDWARE(r128ctx);
+ r128UpdateHWStateLocked(r128ctx);
+ UNLOCK_HARDWARE(r128ctx);
+}
+
+/* Update the driver's state */
+/* NOTE: This function is only called while holding the hardware lock */
+void r128UpdateState(r128ContextPtr r128ctx, int winMoved)
+{
+ R128SAREAPrivPtr sarea = r128ctx->r128Screen->SAREA;
+ int i;
+
+ if (sarea->ctxOwner != r128ctx->driContext->hHWContext) {
+ sarea->ctxOwner = r128ctx->driContext->hHWContext;
+ r128ctx->dirty_context = R128_CTX_ALL_DIRTY;
+ r128LoadContext(r128ctx);
+ }
+
+ for (i = 0; i < r128ctx->r128Screen->NRTexHeaps; i++)
+ r128AgeTextures(r128ctx, i);
+
+ if (winMoved) r128ctx->dirty |= R128_UPDATE_WINPOS;
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_state.h b/xc/lib/GL/mesa/src/drv/r128/r128_state.h
new file mode 100644
index 000000000..f847452f0
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.h
@@ -0,0 +1,50 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_STATE_H_
+#define _R128_STATE_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void r128DDInitState(r128ContextPtr r128ctx);
+extern void r128DDInitStateFuncs(GLcontext *ctx);
+
+extern void r128UpdateState(r128ContextPtr r128ctx, int winMoved);
+extern void r128UpdateHWState(r128ContextPtr r128ctx);
+
+extern void r128SetClipRects(r128ContextPtr r128ctx,
+ XF86DRIClipRectPtr pc, int nc);
+
+#endif
+#endif /* _R128_STATE_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_swap.c b/xc/lib/GL/mesa/src/drv/r128/r128_swap.c
new file mode 100644
index 000000000..6b347023d
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_swap.c
@@ -0,0 +1,125 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+#include "r128_state.h"
+#include "r128_vb.h"
+#include "r128_swap.h"
+
+/* Copy the back color buffer to the front color buffer */
+void r128SwapBuffers(r128ContextPtr r128ctx)
+{
+ unsigned char *R128MMIO = r128ctx->r128Screen->mmio;
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable;
+ int nc;
+ XF86DRIClipRectPtr c;
+ int dst_bpp;
+ CARD32 swapAge;
+
+ if (r128ctx->SWonly) {
+ /* FIXME: Provide software fallback for this case?? */
+ }
+
+ switch (r128ctx->r128Screen->bpp) {
+ case 8:
+ dst_bpp = R128_GMC_DST_8BPP_CI;
+ break;
+ case 16:
+ if (r128ctx->r128Screen->depth == 15) dst_bpp = R128_GMC_DST_15BPP;
+ else dst_bpp = R128_GMC_DST_16BPP;
+ break;
+ case 24:
+ dst_bpp = R128_GMC_DST_24BPP;
+ break;
+ case 32:
+ default:
+ dst_bpp = R128_GMC_DST_32BPP;
+ break;
+ }
+
+ LOCK_HARDWARE(r128ctx);
+
+ /* Flush any outstanding vertex buffers */
+ R128CCE_FLUSH_VB(r128ctx);
+
+ /* Throttle the frame rate -- only allow one pending swap buffers
+ request at a time */
+ while (r128ctx->lastSwapAge > (swapAge = INREG(R128_SWAP_AGE_REG)));
+
+ /* Init the clip rects here in case they changed during the
+ LOCK_HARDWARE macro */
+ c = dPriv->pClipRects;
+ nc = dPriv->numClipRects;
+
+ /* Cycle through the clip rects */
+ while (nc--) {
+ int fx = c[nc].x1;
+ int fy = c[nc].y1;
+ int fw = c[nc].x2 - fx;
+ int fh = c[nc].y2 - fy;
+ int bx = fx + r128ctx->r128Screen->backX;
+ int by = fy + r128ctx->r128Screen->backY;
+
+ fx += r128ctx->r128Screen->fbX;
+ fy += r128ctx->r128Screen->fbY;
+
+ R128CCE3(R128_CCE_PACKET3_CNTL_BITBLT_MULTI, 3);
+ R128CCE(R128_GMC_BRUSH_NONE
+ | R128_GMC_SRC_DATATYPE_COLOR
+ | R128_DP_SRC_SOURCE_MEMORY
+ | dst_bpp
+ | R128_ROP3_S);
+ R128CCE((bx << 16) | by);
+ R128CCE((fx << 16) | fy);
+ R128CCE((fw << 16) | fh);
+ }
+
+ ++swapAge;
+ R128CCE0(R128_CCE_PACKET0, R128_SWAP_AGE_REG, 0);
+ R128CCE(swapAge);
+ r128ctx->lastSwapAge = swapAge;
+
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ALL_DIRTY;
+
+ R128CCE_SUBMIT_PACKETS();
+
+ UNLOCK_HARDWARE(r128ctx);
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_swap.h b/xc/lib/GL/mesa/src/drv/r128/r128_swap.h
new file mode 100644
index 000000000..32851041c
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_swap.h
@@ -0,0 +1,43 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_SWAP_H_
+#define _R128_SWAP_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void r128SwapBuffers(r128ContextPtr r128ctx);
+
+#endif
+#endif /* _R128_SWAP_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c
new file mode 100644
index 000000000..d75345404
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c
@@ -0,0 +1,1851 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Gareth Hughes <gareth@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_state.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+#include "r128_vb.h"
+#include "r128_tex.h"
+
+#include "mmath.h"
+#include "simple_list.h"
+
+static void r128SetTexWrap(r128TexObjPtr t, GLenum srwap, GLenum twrap);
+static void r128SetTexFilter(r128TexObjPtr t, GLenum minf, GLenum magf);
+static void r128SetTexBorderColor(r128TexObjPtr t, GLubyte c[4]);
+
+/* Allocate and initialize hardware state associated with texture `t' */
+/* NOTE: This function is only called while holding the hardware lock */
+static r128TexObjPtr r128CreateTexObj(r128ContextPtr r128ctx,
+ struct gl_texture_object *tObj)
+{
+ r128TexObjPtr t;
+ struct gl_texture_image *image;
+ int log2Pitch, log2Height, log2Size, log2MinSize;
+ int totalSize;
+ int i;
+
+ image = tObj->Image[0];
+ if (!image) return NULL; /* ERROR!!! */
+
+ t = (r128TexObjPtr)calloc(1,sizeof(*t));
+ if (!t) return NULL; /* ERROR!!! */
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API)
+ fprintf(stderr, "r128CreateTexObj(%p)\n", tObj);
+
+ switch (image->Format) {
+ case GL_RGBA:
+ case GL_ALPHA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ if (r128ctx->r128Screen->bpp == 32) {
+ t->texelBytes = 4;
+ t->textureFormat = R128_DATATYPE_ARGB8888;
+ } else {
+ t->texelBytes = 2;
+ t->textureFormat = R128_DATATYPE_ARGB4444;
+ }
+ break;
+
+ case GL_RGB:
+ if (r128ctx->r128Screen->bpp == 32) {
+ t->texelBytes = 4;
+ t->textureFormat = R128_DATATYPE_ARGB8888;
+ } else {
+ t->texelBytes = 2;
+ t->textureFormat = R128_DATATYPE_RGB565;
+ }
+ break;
+
+ case GL_LUMINANCE:
+ if (r128ctx->r128Screen->bpp == 32) {
+ t->texelBytes = 4;
+ t->textureFormat = R128_DATATYPE_ARGB8888;
+ } else {
+ t->texelBytes = 2;
+ /* Use this to get true greys */
+ t->textureFormat = R128_DATATYPE_ARGB1555;
+ }
+ break;
+
+ case GL_COLOR_INDEX:
+ t->texelBytes = 1;
+ t->textureFormat = R128_DATATYPE_CI8;
+ break;
+
+ default:
+ /* ERROR!!! */
+ fprintf(stderr, "r128CreateTexObj: bad image->Format\n");
+ free(t);
+ return NULL;
+ }
+
+ /* Calculate dimensions in log domain */
+ for (i = 1, log2Height = 0; i < image->Height; i *= 2) log2Height++;
+ for (i = 1, log2Pitch = 0; i < image->Width; i *= 2) log2Pitch++;
+ if (image->Width > image->Height) log2Size = log2Pitch;
+ else log2Size = log2Height;
+
+ t->dirty_images = 0;
+
+ /* Calculate mipmap offsets and dimensions */
+ totalSize = 0;
+ for (i = 0; i <= log2Size && tObj->Image[i]; i++) {
+ t->image[i].offset = totalSize;
+ t->image[i].width = tObj->Image[i]->Width;
+ t->image[i].height = tObj->Image[i]->Height;
+ t->dirty_images |= 1 << i;
+ totalSize += (tObj->Image[i]->Height *
+ tObj->Image[i]->Width *
+ t->texelBytes);
+
+ /* Offsets must be 32-byte aligned for host data blits */
+ totalSize = (totalSize + 31) & ~31;
+ }
+ log2MinSize = log2Size - i + 1;
+
+ t->totalSize = totalSize;
+ t->internFormat = image->IntFormat;
+
+ t->bound = 0;
+ t->heap = 0; /* This is set in r128UploadTexImages */
+ t->tObj = tObj;
+
+ t->memBlock = NULL;
+ t->bufAddr = NULL;
+
+ t->regs.tex_cntl = t->textureFormat;
+ t->regs.size_pitch = ((log2Pitch << R128_TEX_PITCH_SHIFT) |
+ (log2Size << R128_TEX_SIZE_SHIFT) |
+ (log2Height << R128_TEX_HEIGHT_SHIFT) |
+ (log2MinSize << R128_TEX_MIN_SIZE_SHIFT));
+ t->regs.border_color = 0x00000000;
+
+ if (log2MinSize == log2Size ||
+ log2MinSize != 0)
+ t->regs.tex_cntl |= R128_MIP_MAP_DISABLE;
+
+ r128SetTexWrap(t, tObj->WrapS, tObj->WrapT);
+ r128SetTexFilter(t, tObj->MinFilter, tObj->MagFilter);
+ r128SetTexBorderColor(t, tObj->BorderColor);
+
+ tObj->DriverData = t;
+
+ make_empty_list(t);
+
+ return t;
+}
+
+/* Destroy hardware state associated with texture `t' */
+/* NOTE: This function can be called while holding the hardware lock and
+ while not holding the lock*/
+void r128DestroyTexObj(r128ContextPtr r128ctx, r128TexObjPtr t)
+{
+ if (!t) return;
+
+ if (t->memBlock) {
+ mmFreeMem(t->memBlock);
+ t->memBlock = NULL;
+ }
+
+ if (t->tObj) t->tObj->DriverData = NULL;
+ if (t->bound) r128ctx->CurrentTexObj[t->bound-1] = NULL;
+
+ remove_from_list(t);
+ free(t);
+}
+
+/* Keep track of swapped out texture objects */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128SwapOutTexObj(r128ContextPtr r128ctx, r128TexObjPtr t)
+{
+ if (t->memBlock) {
+ mmFreeMem(t->memBlock);
+ t->memBlock = NULL;
+ }
+
+ t->dirty_images = ~0;
+ move_to_tail(&r128ctx->SwappedOut, t);
+}
+
+/* Print out debugging information about texture LRU */
+void r128PrintLocalLRU(r128ContextPtr r128ctx, int heap)
+{
+ r128TexObjPtr t;
+ int sz = 1 << (r128ctx->r128Screen->log2TexGran[heap]);
+
+ foreach(t, &r128ctx->TexObjList[heap]) {
+ if (!t->tObj) {
+ fprintf(stderr, "Placeholder %d at 0x%x sz 0x%x\n",
+ t->memBlock->ofs / sz,
+ t->memBlock->ofs,
+ t->memBlock->size);
+ } else {
+ fprintf(stderr, "Texture (bound %d) at 0x%x sz 0x%x\n",
+ t->bound,
+ t->memBlock->ofs,
+ t->memBlock->size);
+ }
+ }
+}
+
+void r128PrintGlobalLRU(r128ContextPtr r128ctx, int heap)
+{
+ R128TexRegion *list = r128ctx->r128Screen->SAREA->texList[heap];
+ int i, j;
+
+ for (i = 0, j = R128_NR_TEX_REGIONS ; i < R128_NR_TEX_REGIONS ; i++) {
+ fprintf(stderr, "list[%d] age %d next %d prev %d\n",
+ j, list[j].age, list[j].next, list[j].prev);
+ j = list[j].next;
+ if (j == R128_NR_TEX_REGIONS) break;
+ }
+
+ if (j != R128_NR_TEX_REGIONS) {
+ fprintf(stderr, "Loop detected in global LRU\n");
+ }
+}
+
+/* Reset the global texture LRU */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128ResetGlobalLRU(r128ContextPtr r128ctx, int heap)
+{
+ R128TexRegion *list = r128ctx->r128Screen->SAREA->texList[heap];
+ int log2sz = 1 << r128ctx->r128Screen->log2TexGran[heap];
+ int i;
+
+ /*
+ * (Re)initialize the global circular LRU list. The last element in
+ * the array (R128_NR_TEX_REGIONS) is the sentinal. Keeping it at
+ * the end of the array allows it to be addressed rationally when
+ * looking up objects at a particular location in texture memory.
+ */
+
+ for (i = 0; (i+1) * log2sz <= r128ctx->r128Screen->texSize[heap]; i++) {
+ list[i].prev = i-1;
+ list[i].next = i+1;
+ list[i].age = 0;
+ }
+
+ i--;
+ list[0].prev = R128_NR_TEX_REGIONS;
+ list[i].prev = i-1;
+ list[i].next = R128_NR_TEX_REGIONS;
+ list[R128_NR_TEX_REGIONS].prev = i;
+ list[R128_NR_TEX_REGIONS].next = 0;
+ r128ctx->r128Screen->SAREA->texAge[heap] = 0;
+}
+
+/* Update the local and glock texture LRUs */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128UpdateTexLRU(r128ContextPtr r128ctx, r128TexObjPtr t)
+{
+ int heap = t->heap;
+ R128TexRegion *list = r128ctx->r128Screen->SAREA->texList[heap];
+ int log2sz = r128ctx->r128Screen->log2TexGran[heap];
+
+ int start = t->memBlock->ofs >> log2sz;
+ int end = (t->memBlock->ofs + t->memBlock->size-1) >> log2sz;
+ int i;
+
+ r128ctx->lastTexAge[heap] = ++r128ctx->r128Screen->SAREA->texAge[heap];
+
+ /* Update our local LRU */
+ move_to_head(&r128ctx->TexObjList[heap], t);
+
+ /* Update the global LRU */
+ for (i = start ; i <= end ; i++) {
+ list[i].in_use = 1;
+ list[i].age = r128ctx->lastTexAge[heap];
+
+ /* remove_from_list(i) */
+ list[(CARD32)list[i].next].prev = list[i].prev;
+ list[(CARD32)list[i].prev].next = list[i].next;
+
+ /* insert_at_head(list, i) */
+ list[i].prev = R128_NR_TEX_REGIONS;
+ list[i].next = list[R128_NR_TEX_REGIONS].next;
+ list[(CARD32)list[R128_NR_TEX_REGIONS].next].prev = i;
+ list[R128_NR_TEX_REGIONS].next = i;
+ }
+}
+
+/* Update our notion of what textures have been changed since we last
+ held the lock. This pertains to both our local textures and the
+ textures belonging to other clients. Keep track of other client's
+ textures by pushing a placeholder texture onto the LRU list -- these
+ are denoted by (tObj == NULL). */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128TexturesGone(r128ContextPtr r128ctx, int heap,
+ int offset, int size, int in_use)
+{
+ r128TexObjPtr t, tmp;
+
+ foreach_s (t, tmp, &r128ctx->TexObjList[heap]) {
+ if (t->memBlock->ofs >= offset + size ||
+ t->memBlock->ofs + t->memBlock->size <= offset)
+ continue;
+
+ /* It overlaps - kick it out. Need to hold onto the currently
+ bound objects, however. */
+ if (t->bound) r128SwapOutTexObj(r128ctx, t);
+ else r128DestroyTexObj(r128ctx, t);
+ }
+
+ if (in_use) {
+ t = (r128TexObjPtr) calloc(1,sizeof(*t));
+ if (!t) return;
+
+ t->memBlock = mmAllocMem(r128ctx->texHeap[heap], size, 0, offset);
+ insert_at_head(&r128ctx->TexObjList[heap], t);
+ }
+}
+
+/* Update our client's shared texture state. If another client has
+ modified a region in which we have textures, then we need to figure
+ out which of our textures has been removed, and update our global
+ LRU. */
+void r128AgeTextures(r128ContextPtr r128ctx, int heap)
+{
+ R128SAREAPrivPtr sarea = r128ctx->r128Screen->SAREA;
+
+ if (sarea->texAge[heap] != r128ctx->lastTexAge[heap]) {
+ int log2sz = 1 << r128ctx->r128Screen->log2TexGran[heap];
+ int nr = 0;
+ int idx;
+
+ for (idx = sarea->texList[heap][R128_NR_TEX_REGIONS].prev;
+ idx != R128_NR_TEX_REGIONS && nr < R128_NR_TEX_REGIONS;
+ idx = sarea->texList[heap][idx].prev, nr++) {
+
+ /* If switching texturing schemes, then the SAREA might not
+ have been properly cleared, so we need to reset the
+ global texture LRU. */
+ if (idx * log2sz > r128ctx->r128Screen->texSize[heap]) {
+ nr = R128_NR_TEX_REGIONS;
+ break;
+ }
+
+ if (sarea->texList[heap][idx].age > r128ctx->lastTexAge[heap])
+ r128TexturesGone(r128ctx, heap, idx * log2sz, log2sz,
+ sarea->texList[heap][idx].in_use);
+ }
+
+ if (nr == R128_NR_TEX_REGIONS) {
+ r128TexturesGone(r128ctx, heap,
+ 0, r128ctx->r128Screen->texSize[heap], 0);
+ r128ResetGlobalLRU(r128ctx, heap);
+ }
+
+ r128ctx->dirty |= R128_UPDATE_TEX0IMAGES;
+ r128ctx->dirty |= R128_UPDATE_TEX1IMAGES;
+ r128ctx->lastTexAge[heap] = sarea->texAge[heap];
+ }
+}
+
+/* Convert a block of Mesa-formatted texture to an 8bpp hardware format */
+static void r128ConvertTexture8bpp(r128ContextPtr r128ctx,
+ struct gl_texture_image *image,
+ int x, int y, int width, int height,
+ int pitch)
+{
+ CARD8 *src;
+ CARD32 pix;
+ int i, j;
+
+ switch (image->Format) {
+ case GL_RGB:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3;
+ for (j = width >> 2; j; j--) {
+ pix = ((R128PACKCOLOR332( src[0], src[1], src[2]) ) |
+ (R128PACKCOLOR332( src[3], src[4], src[5]) << 8) |
+ (R128PACKCOLOR332( src[6], src[7], src[8]) << 16) |
+ (R128PACKCOLOR332( src[9], src[10], src[11]) << 24));
+ R128CCE(pix);
+ src += 12;
+ }
+ }
+ break;
+
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_INTENSITY:
+ case GL_COLOR_INDEX:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for (j = width >> 2; j; j--) {
+ pix = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
+ R128CCE(pix);
+ src += 4;
+ }
+ }
+ break;
+
+ default:
+ fprintf(stderr, "r128ConvertTexture8bpp: unsupported format 0x%x\n",
+ image->Format);
+ }
+}
+
+/* Convert a block of Mesa-formatted texture to a 16bpp hardware format */
+static void r128ConvertTexture16bpp(r128ContextPtr r128ctx,
+ struct gl_texture_image *image,
+ int x, int y, int width, int height,
+ int pitch)
+{
+ CARD8 *src;
+ CARD32 pix;
+ int i, j;
+
+ switch (image->Format) {
+ case GL_RGB:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3;
+ for (j = width >> 1; j; j--) {
+ pix = ((R128PACKCOLOR565(src[0], src[1], src[2]) ) |
+ (R128PACKCOLOR565(src[3], src[4], src[5]) << 16));
+ R128CCE(pix);
+ src += 6;
+ }
+ }
+ break;
+
+ case GL_RGBA:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4;
+ for (j = width >> 1; j; j--) {
+ pix =
+ ((R128PACKCOLOR4444(src[0], src[1], src[2], src[3]) ) |
+ (R128PACKCOLOR4444(src[4], src[5], src[6], src[7])<<16));
+ R128CCE(pix);
+ src += 8;
+ }
+ }
+ break;
+
+ case GL_ALPHA:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for (j = width >> 1; j; j--) {
+ pix = ((R128PACKCOLOR4444(0xff, 0xff, 0xff, src[0]) ) |
+ (R128PACKCOLOR4444(0xff, 0xff, 0xff, src[1]) << 16));
+ R128CCE(pix);
+ src += 2;
+ }
+ }
+ break;
+
+ case GL_LUMINANCE:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for (j = width >> 1; j; j--) {
+ pix = ((R128PACKCOLOR1555(src[0], src[0], src[0], 0xff) ) |
+ (R128PACKCOLOR1555(src[1], src[1], src[1], 0xff)<<16));
+ R128CCE(pix);
+ src += 2;
+ }
+ }
+ break;
+
+ case GL_LUMINANCE_ALPHA:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 2;
+ for (j = width >> 1; j; j--) {
+ pix =
+ ((R128PACKCOLOR4444(src[0], src[0], src[0], src[1]) ) |
+ (R128PACKCOLOR4444(src[2], src[2], src[2], src[3])<<16));
+ R128CCE(pix);
+ src += 4;
+ }
+ }
+ break;
+
+ case GL_INTENSITY:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for (j = width >> 1; j; j--) {
+ pix =
+ ((R128PACKCOLOR4444(src[0], src[0], src[0], src[0]) ) |
+ (R128PACKCOLOR4444(src[1], src[1], src[1], src[1])<<16));
+ R128CCE(pix);
+ src += 2;
+ }
+ }
+ break;
+
+ default:
+ fprintf(stderr, "r128ConvertTexture16bpp: unsupported format 0x%x\n",
+ image->Format);
+ }
+}
+
+/* Convert a block of Mesa-formatted texture to a 32bpp hardware format */
+static void r128ConvertTexture32bpp(r128ContextPtr r128ctx,
+ struct gl_texture_image *image,
+ int x, int y, int width, int height,
+ int pitch)
+{
+ CARD8 *src;
+ CARD32 pix;
+ int i, j;
+
+ switch (image->Format) {
+ case GL_RGB:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3;
+ for (j = width; j; j--) {
+ pix = R128PACKCOLOR8888(src[0], src[1], src[2], 0xff);
+ R128CCE(pix);
+ src += 3;
+ }
+ }
+ break;
+
+ case GL_RGBA:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4;
+ for (j = width; j; j--) {
+ pix = R128PACKCOLOR8888(src[0], src[1], src[2], src[3]);
+ R128CCE(pix);
+ src += 4;
+ }
+ }
+ break;
+
+ case GL_ALPHA:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for (j = width; j; j--) {
+ pix = R128PACKCOLOR8888(0xff, 0xff, 0xff, src[0]);
+ R128CCE(pix);
+ src += 1;
+ }
+ }
+ break;
+
+ case GL_LUMINANCE:
+ for (i = 0 ; i < height ; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for (j = width; j; j--) {
+ pix = R128PACKCOLOR8888(src[0], src[0], src[0], 0xff);
+ R128CCE(pix);
+ src += 1;
+ }
+ }
+ break;
+
+ case GL_LUMINANCE_ALPHA:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 2;
+ for (j = width; j; j-- ) {
+ pix = R128PACKCOLOR8888(src[0], src[0], src[0], src[1]);
+ R128CCE(pix);
+ src += 2;
+ }
+ }
+ break;
+
+ case GL_INTENSITY:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for (j = width; j; j--) {
+ pix = R128PACKCOLOR8888(src[0], src[0], src[0], src[0]);
+ R128CCE(pix);
+ src += 1;
+ }
+ }
+ break;
+
+ default:
+ fprintf(stderr, "r128ConvertTexture32bpp: unsupported format 0x%x\n",
+ image->Format);
+ }
+}
+
+/* Upload the texture image associated with texture `t' at level `level'
+ at the address relative to `start'. */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128UploadSubImage(r128ContextPtr r128ctx,
+ r128TexObjPtr t, int level,
+ int x, int y, int width, int height)
+{
+ struct gl_texture_image *image;
+ int texelsPerDword = 0;
+ int imageWidth, imageHeight;
+ int remaining, rows;
+ int format, pitch, dwords;
+ CARD32 offset;
+
+ /* Ensure we have a valid texture to upload */
+ if (level < 0 || level > R128_TEX_MAXLEVELS) return;
+ if (!(image = t->tObj->Image[level])) return;
+
+ /* FIXME: support RGB888 (i.e., 24bpp) textures? */
+ switch (t->texelBytes) {
+ case 1: texelsPerDword = 4; break;
+ case 2: texelsPerDword = 2; break;
+ case 4: texelsPerDword = 1; break;
+ }
+
+ imageWidth = image->Width;
+ imageHeight = image->Height;
+
+ format = t->textureFormat >> 16;
+
+ /* The texel upload routines have a minimum width, so force the size
+ if needed */
+ if (imageWidth < texelsPerDword) {
+ int factor;
+
+ factor = texelsPerDword / imageWidth;
+ imageWidth = texelsPerDword;
+ imageHeight /= factor;
+ if (imageHeight == 0) {
+ /* In this case, the texel converter will actually walk a
+ texel or two off the end of the image, but normal malloc
+ alignment should prevent it from ever causing a fault. */
+ imageHeight = 1;
+ }
+ }
+
+ /* We can't upload to a pitch less than 8 texels so we will need to
+ linearly upload all modified rows for textures smaller than this.
+ This makes the x/y/width/height different for the blitter and the
+ texture walker. */
+ if (imageWidth >= 8) {
+ /* The texture walker and the blitter look identical */
+ pitch = imageWidth >> 3;
+ } else {
+ int factor;
+ int y2;
+ int start, end;
+
+ start = (y * imageWidth) & ~7;
+ end = (y + height) * imageWidth;
+
+ if (end - start < 8) {
+ /* Handle the case where the total number of texels uploaded
+ is < 8 */
+ x = 0;
+ y = start / 8;
+ width = end - start;
+ height = 1;
+ } else {
+ /* Upload some number of full 8 texel blit rows */
+ factor = 8 / imageWidth;
+
+ y2 = y + height - 1;
+ y /= factor;
+ y2 /= factor;
+
+ x = 0;
+ width = 8;
+ height = y2 - y + 1;
+ }
+
+ /* Fixed pitch of 8 */
+ pitch = 1;
+ }
+
+ dwords = width * height / texelsPerDword;
+ offset = (CARD32)(t->bufAddr + t->image[level].offset);
+
+ /* Fix offset for AGP textures */
+ if (t->heap == R128_AGP_TEX_HEAP)
+ offset += R128_AGP_TEX_OFFSET + r128ctx->r128Screen->agpTexOffset;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) {
+ fprintf(stderr, "r128UploadSubImage: %d,%d of %d,%d at %d,%d\n",
+ width, height, image->Width, image->Height, x, y);
+ fprintf(stderr, " blit ofs: 0x%08x pitch: 0x%x dwords: %d "
+ "level: %d format: %x\n",
+ (int)offset, pitch, dwords, level, format);
+ }
+
+ /* Subdivide the texture if required */
+ if (dwords < R128_CCE_PACKET_MAX_DWORDS) {
+ rows = height;
+ } else {
+ rows = (R128_CCE_PACKET_MAX_DWORDS * texelsPerDword) / (2 * width);
+ }
+
+ /* Flush the pixel cache, and mark the contents as Read Invalid */
+ R128CCE0(R128_CCE_PACKET0, R128_PC_GUI_CTLSTAT, 0);
+ R128CCE(r128ctx->regs.pc_gui_ctlstat |
+ R128_PC_RI_GUI |
+ R128_PC_FLUSH_GUI);
+ R128CCE_SUBMIT_PACKETS();
+
+ /* Build the CCE host data blit header */
+ R128CCE3(R128_CCE_PACKET3_CNTL_HOSTDATA_BLT, 0);
+
+ /* DP_GUI_MASTER_CNTL */
+ R128CCE(R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_NONE |
+ (format << 8) |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_S |
+ R128_DP_SRC_SOURCE_HOST_DATA |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_AUX_CLIP_DIS |
+ R128_GMC_WR_MSK_DIS );
+
+ /* DST_OFFSET_PITCH - fixed at the moment until we get better ring
+ control */
+ R128CCE((pitch << 21) | (offset>>5));
+
+ /* FRGD_COLOR, BKGD_COLOR */
+ R128CCE(0xffffffff);
+ R128CCE(0xffffffff);
+
+ for (remaining = height; remaining > 0; remaining -= rows, y += rows) {
+ height = (remaining >= rows) ? rows : remaining;
+ dwords = width * height / texelsPerDword;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) {
+ fprintf(stderr, " blitting: %d,%d at %d,%d - %d dwords\n",
+ width, height, x, y, dwords);
+ }
+
+ r128ctx->CCEbuf[0] &= ~R128_CCE_PACKET_COUNT_MASK;
+ r128ctx->CCEbuf[0] |= (dwords + 6) << 16;
+
+ /* Blit coords, size */
+ R128CCE((y << 16) | x);
+ R128CCE((height << 16) | width);
+ R128CCE(dwords);
+
+ /* Actually do the texture conversion */
+ switch (t->texelBytes) {
+ case 1:
+ r128ConvertTexture8bpp(r128ctx, image,
+ x, y, width, height, width);
+ break;
+ case 2:
+ r128ConvertTexture16bpp(r128ctx, image,
+ x, y, width, height, width);
+ break;
+ case 4:
+ r128ConvertTexture32bpp(r128ctx,
+ image, x, y, width, height, width);
+ break;
+ }
+
+ /* Flush the pixel cache */
+ R128CCE0(R128_CCE_PACKET0, R128_PC_GUI_CTLSTAT, 0 );
+ R128CCE(r128ctx->regs.pc_gui_ctlstat | R128_PC_FLUSH_GUI);
+
+ /* Save the partial blit header */
+ R128CCE_SUBMIT_PACKETS();
+ r128ctx->CCEcount = 5;
+ }
+
+ /* Clean up CCE ring buffer */
+ r128ctx->CCEcount = 0;
+}
+
+/* Upload the texture images associated with texture `t'. This might
+ require removing our own and/or other client's texture objects to
+ make room for these images. */
+/* NOTE: This function is only called while holding the hardware lock */
+int r128UploadTexImages(r128ContextPtr r128ctx, r128TexObjPtr t)
+{
+ int i;
+ int minLevel;
+ int maxLevel;
+ int heap;
+
+ if (!t) return 0;
+
+ /* Choose the heap appropriately */
+ heap = t->heap = R128_LOCAL_TEX_HEAP;
+ if (!r128ctx->r128Screen->IsPCI &&
+ t->totalSize > r128ctx->r128Screen->texSize[heap])
+ heap = t->heap = R128_AGP_TEX_HEAP;
+
+ /* Do we need to eject LRU texture objects? */
+ if (!t->memBlock) {
+ /* Allocate a memory block on a 4k boundary (1<<12 == 4096) */
+ t->memBlock = mmAllocMem(r128ctx->texHeap[heap], t->totalSize, 12, 0);
+
+ /* Try AGP before kicking anything out of local mem */
+ if (!t->memBlock && heap == R128_LOCAL_TEX_HEAP) {
+ t->memBlock = mmAllocMem(r128ctx->texHeap[R128_AGP_TEX_HEAP],
+ t->totalSize, 12, 0);
+
+ if (t->memBlock) heap = t->heap = R128_AGP_TEX_HEAP;
+ }
+
+ /* Kick out textures until the requested texture fits */
+ while (!t->memBlock) {
+ if (r128ctx->TexObjList[heap].prev->bound) {
+ fprintf(stderr,
+ "r128UploadTexImages: ran into bound texture\n");
+ return -1;
+ }
+ if (r128ctx->TexObjList[heap].prev ==
+ &(r128ctx->TexObjList[heap])) {
+ if (r128ctx->r128Screen->IsPCI) {
+ fprintf(stderr, "r128UploadTexImages: upload texture "
+ "failure on local texture heaps, sz=%d\n",
+ t->totalSize);
+ return -1;
+ } else if (heap == R128_LOCAL_TEX_HEAP) {
+ heap = t->heap = R128_AGP_TEX_HEAP;
+ continue;
+ } else {
+ fprintf(stderr, "r128UploadTexImages: upload texture "
+ "failure on both local and AGP texture heaps, "
+ "sz=%d\n",
+ t->totalSize);
+ return -1;
+ }
+ }
+
+ r128DestroyTexObj(r128ctx, r128ctx->TexObjList[heap].prev);
+
+ t->memBlock = mmAllocMem(r128ctx->texHeap[heap],
+ t->totalSize, 12, 0);
+ }
+
+ /* Set the base offset of the texture image */
+ t->bufAddr = (unsigned char *)r128ctx->r128Screen->texOffset[heap];
+ t->bufAddr += t->memBlock->ofs;
+
+ maxLevel = ((t->regs.size_pitch & R128_TEX_SIZE_MASK) >>
+ R128_TEX_SIZE_SHIFT);
+ minLevel = ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >>
+ R128_TEX_MIN_SIZE_SHIFT);
+
+ /* Update the hardware's texture image addresses */
+ switch (t->bound) {
+ case 1:
+ /* Set texture offsets */
+ if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) {
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.prim_tex_offset[i] = (CARD32)t->bufAddr;
+ } else {
+ for (i = maxLevel; i >= minLevel; i--)
+ r128ctx->regs.prim_tex_offset[i] =
+ t->image[maxLevel-i].offset + (CARD32)t->bufAddr;
+ }
+ /* Fix AGP texture offsets */
+ if (heap == R128_AGP_TEX_HEAP)
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.prim_tex_offset[i] +=
+ R128_AGP_TEX_OFFSET +
+ r128ctx->r128Screen->agpTexOffset;
+ /* Force loading the new state into the hardware */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_TEX0STATE;
+ break;
+
+ case 2:
+ /* Set texture offsets */
+ if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) {
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.sec_tex_offset[i] = (CARD32)t->bufAddr;
+ } else {
+ for (i = maxLevel; i >= minLevel; i--)
+ r128ctx->regs.sec_tex_offset[i] =
+ t->image[maxLevel-i].offset + (CARD32)t->bufAddr;
+ }
+ /* Fix AGP texture offsets */
+ if (heap == R128_AGP_TEX_HEAP)
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.sec_tex_offset[i] +=
+ R128_AGP_TEX_OFFSET +
+ r128ctx->r128Screen->agpTexOffset;
+ /* Force loading the new state into the hardware */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_TEX1STATE;
+ break;
+
+ default:
+ return -1;
+ }
+ }
+
+ /* Let the world know we've used this memory recently */
+ r128UpdateTexLRU(r128ctx, t);
+
+ /* Upload any images that are new */
+ if (t->dirty_images) {
+ int num_levels = (((t->regs.size_pitch & R128_TEX_SIZE_MASK) >>
+ R128_TEX_SIZE_SHIFT) -
+ ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >>
+ R128_TEX_MIN_SIZE_SHIFT));
+
+ for (i = 0; i <= num_levels; i++) {
+ if (t->dirty_images & (1<<i)) {
+ r128UploadSubImage(r128ctx, t, i, 0, 0,
+ t->image[i].width, t->image[i].height);
+ }
+ }
+
+ r128ctx->regs.tex_cntl_c |= R128_TEX_CACHE_FLUSH;
+
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ENGINESTATE;
+ }
+
+ t->dirty_images = 0;
+ return 0;
+}
+
+/* Update the hardware state for texture unit 0 */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128UpdateTex0State(r128ContextPtr r128ctx)
+{
+ GLcontext *ctx = r128ctx->glCtx;
+ r128TexObjPtr t;
+ struct gl_texture_object *tObj;
+ int i;
+ CARD32 tex_size_pitch, tex_combine_cntl;
+
+ /* Only update the hardware texture state if the texture is current,
+ complete and enabled. */
+ if (!(tObj = ctx->Texture.Unit[0].Current)) return;
+ if ((tObj != ctx->Texture.Unit[0].CurrentD[2]) &&
+ (tObj != ctx->Texture.Unit[0].CurrentD[1])) return;
+ if (!tObj->Complete) return;
+
+ /* If neither tex0 nor tex1 is enabled, then disable tex0. However,
+ if tex1 is enabled but tex0 is disabled, then we need to enable
+ tex0 and have it to copy the input (see how tex_combine_cntl is
+ setup below). */
+ if (!(ctx->Texture.Enabled & (ENABLE_TEX0 | ENABLE_TEX1))) {
+ r128ctx->regs.tex_cntl_c &= ~R128_TEXMAP_ENABLE;
+ return;
+ }
+
+ /* If this is the first time the texture has been used, then create
+ a new texture object for it. */
+ t = tObj->DriverData;
+ if (!t) t = r128CreateTexObj(r128ctx, tObj);
+ if (!t) return;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API)
+ fprintf(stderr, "r128UpdateTex0State(%p, 0x%08x)\n",
+ tObj, (int)t->dirty_images);
+
+ /* Force any texture images to be loaded into the hardware */
+ if (t->dirty_images) r128ctx->dirty |= R128_UPDATE_TEX0IMAGES;
+
+ /* Bind texture to texture 0 unit */
+ r128ctx->CurrentTexObj[0] = t;
+ t->bound = 1;
+
+ if (t->memBlock) r128UpdateTexLRU(r128ctx, t);
+
+ /* Set the texture environment state */
+ switch (ctx->Texture.Unit[0].EnvMode) {
+ case GL_REPLACE:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ tex_combine_cntl = (R128_COMB_DIS |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_DIS |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_RGB:
+ case GL_LUMINANCE:
+ tex_combine_cntl = (R128_COMB_DIS |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_ALPHA:
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_DIS |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_BLEND:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ case GL_LUMINANCE_ALPHA:
+ switch (r128ctx->regs.constant_color_c &
+ R128_CONSTANT_COLOR_MASK) {
+ case R128_CONSTANT_COLOR_ZERO:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_NTEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case R128_CONSTANT_COLOR_ONE:
+ default:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ r128ctx->Fallback |= R128_FALLBACK_TEXTURE;
+ break;
+ }
+ break;
+ case GL_RGB:
+ case GL_LUMINANCE:
+ switch (r128ctx->regs.constant_color_c &
+ R128_CONSTANT_COLOR_MASK) {
+ case R128_CONSTANT_COLOR_ZERO:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_NTEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case R128_CONSTANT_COLOR_ONE:
+ default:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ r128ctx->Fallback |= R128_FALLBACK_TEXTURE;
+ break;
+ }
+ break;
+ case GL_ALPHA:
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_INTENSITY:
+ switch (r128ctx->regs.constant_color_c &
+ R128_CONSTANT_COLOR_MASK) {
+ case R128_CONSTANT_COLOR_ZERO:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_NTEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_NTEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case R128_CONSTANT_COLOR_ONE:
+ default:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ r128ctx->Fallback |= R128_FALLBACK_TEXTURE;
+ break;
+ }
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_MODULATE:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_RGB:
+ case GL_LUMINANCE:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_ALPHA:
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_DECAL:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ tex_combine_cntl = (R128_COMB_BLEND_TEXTURE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_RGB:
+ tex_combine_cntl = (R128_COMB_DIS |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ /* Undefined behaviour - just copy the input */
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_ADD:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ tex_combine_cntl = (R128_COMB_ADD |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_RGB:
+ case GL_LUMINANCE:
+ tex_combine_cntl = (R128_COMB_ADD |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_ALPHA:
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ /* If tex0 is disabled, then make sure it just copies the input */
+ if (!(ctx->Texture.Enabled & ENABLE_TEX0))
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+
+ /* Enable tex0 */
+ r128ctx->regs.tex_cntl_c |= R128_TEXMAP_ENABLE;
+
+ tex_size_pitch = r128ctx->regs.tex_size_pitch_c;
+ tex_size_pitch &= ~R128_TEX_SIZE_PITCH_MASK;
+ tex_size_pitch |= t->regs.size_pitch << R128_TEX_SIZE_PITCH_SHIFT;
+
+ /* Set the primary texture state in r128ctx->regs */
+ r128ctx->regs.prim_tex_cntl_c = t->regs.tex_cntl;
+ r128ctx->regs.prim_texture_combine_cntl_c = tex_combine_cntl;
+ r128ctx->regs.tex_size_pitch_c = tex_size_pitch;
+ r128ctx->regs.prim_texture_border_color_c = t->regs.border_color;
+
+ /* Set texture offsets */
+ if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) {
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.prim_tex_offset[i] = (CARD32)t->bufAddr;
+ } else {
+ int maxLevel = ((t->regs.size_pitch & R128_TEX_SIZE_MASK) >>
+ R128_TEX_SIZE_SHIFT);
+ int minLevel = ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >>
+ R128_TEX_MIN_SIZE_SHIFT);
+ for (i = maxLevel; i >= minLevel; i--)
+ r128ctx->regs.prim_tex_offset[i] =
+ t->image[maxLevel-i].offset + (CARD32)t->bufAddr;
+ }
+ /* Fix AGP texture offsets */
+ if (t->heap == R128_AGP_TEX_HEAP)
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.prim_tex_offset[i] +=
+ R128_AGP_TEX_OFFSET + r128ctx->r128Screen->agpTexOffset;
+
+ /* Force loading the new state into the hardware */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_TEX0STATE | R128_CTX_ENGINESTATE;
+}
+
+/* Update the hardware state for texture unit 1 */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128UpdateTex1State(r128ContextPtr r128ctx)
+{
+ GLcontext *ctx = r128ctx->glCtx;
+ r128TexObjPtr t;
+ struct gl_texture_object *tObj;
+ int i;
+ CARD32 tex_size_pitch, tex_combine_cntl, tex_cntl;
+
+ /* Only update the hardware texture state if the texture is current,
+ complete and enabled. */
+ if (!(tObj = ctx->Texture.Unit[1].Current)) return;
+ if ((tObj != ctx->Texture.Unit[1].CurrentD[2]) &&
+ (tObj != ctx->Texture.Unit[1].CurrentD[1])) return;
+ if (!tObj->Complete) return;
+
+ /* If tex1 is not enabled, then disable it */
+ if (!(ctx->Texture.Enabled & ENABLE_TEX1)) {
+ r128ctx->regs.tex_cntl_c &= ~R128_SEC_TEXMAP_ENABLE;
+ return;
+ }
+
+ /* If this is the first time the texture has been used, then create
+ a new texture object for it. */
+ t = tObj->DriverData;
+ if (!t) t = r128CreateTexObj(r128ctx, tObj);
+ if (!t) return;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API)
+ fprintf(stderr, "r128UpdateTex1State(%p, 0x%08x)\n",
+ tObj, (int)t->dirty_images);
+
+ /* Force any texture images to be loaded into the hardware */
+ if (t->dirty_images) r128ctx->dirty |= R128_UPDATE_TEX1IMAGES;
+
+ /* Bind texture to texture 1 unit */
+ r128ctx->CurrentTexObj[1] = t;
+ t->bound = 2;
+
+ if (t->memBlock) r128UpdateTexLRU(r128ctx, t);
+
+ /* Set the texture environment state */
+ switch (ctx->Texture.Unit[1].EnvMode) {
+ case GL_REPLACE:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ tex_combine_cntl = (R128_COMB_DIS |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_DIS |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_RGB:
+ case GL_LUMINANCE:
+ tex_combine_cntl = (R128_COMB_DIS |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_ALPHA:
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_DIS |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_BLEND:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ case GL_LUMINANCE_ALPHA:
+ switch ( r128ctx->regs.constant_color_c & R128_CONSTANT_COLOR_MASK ) {
+ case R128_CONSTANT_COLOR_ZERO:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_NTEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case R128_CONSTANT_COLOR_ONE:
+ default:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ r128ctx->Fallback |= R128_FALLBACK_TEXTURE;
+ break;
+ }
+ break;
+ case GL_RGB:
+ case GL_LUMINANCE:
+ switch (r128ctx->regs.constant_color_c &
+ R128_CONSTANT_COLOR_MASK) {
+ case R128_CONSTANT_COLOR_ZERO:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_NTEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA );
+ break;
+ case R128_CONSTANT_COLOR_ONE:
+ default:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA );
+ r128ctx->Fallback |= R128_FALLBACK_TEXTURE;
+ break;
+ }
+ break;
+ case GL_ALPHA:
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_INTENSITY:
+ switch (r128ctx->regs.constant_color_c &
+ R128_CONSTANT_COLOR_MASK) {
+ case R128_CONSTANT_COLOR_ZERO:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_NTEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_NTEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case R128_CONSTANT_COLOR_ONE:
+ default:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ r128ctx->Fallback |= R128_FALLBACK_TEXTURE;
+ break;
+ }
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_MODULATE:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_RGB:
+ case GL_LUMINANCE:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_ALPHA:
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_DECAL:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ tex_combine_cntl = (R128_COMB_BLEND_TEXTURE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_RGB:
+ tex_combine_cntl = (R128_COMB_DIS |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ /* Undefined behaviour - just copy the input */
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_ADD:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ tex_combine_cntl = (R128_COMB_ADD |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_RGB:
+ case GL_LUMINANCE:
+ tex_combine_cntl = (R128_COMB_ADD |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_ALPHA:
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ /* Enable tex1 */
+ r128ctx->regs.tex_cntl_c |= R128_SEC_TEXMAP_ENABLE;
+
+ tex_size_pitch = r128ctx->regs.tex_size_pitch_c;
+ tex_size_pitch &= ~R128_SEC_TEX_SIZE_PITCH_MASK;
+ tex_size_pitch |= t->regs.size_pitch << R128_SEC_TEX_SIZE_PITCH_SHIFT;
+
+ tex_cntl = t->regs.tex_cntl | R128_SEC_SELECT_SEC_ST;
+
+ /* Set the secondary texture state in r128ctx->regs */
+ r128ctx->regs.sec_tex_cntl_c = tex_cntl;
+ r128ctx->regs.sec_tex_combine_cntl_c = tex_combine_cntl;
+ r128ctx->regs.tex_size_pitch_c = tex_size_pitch;
+ r128ctx->regs.sec_texture_border_color_c = t->regs.border_color;
+
+ /* Set texture offsets */
+ if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) {
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.sec_tex_offset[i] = (CARD32)t->bufAddr;
+ } else {
+ int maxLevel = ((t->regs.size_pitch & R128_TEX_SIZE_MASK) >>
+ R128_TEX_SIZE_SHIFT);
+ int minLevel = ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >>
+ R128_TEX_MIN_SIZE_SHIFT);
+ for (i = maxLevel; i >= minLevel; i--)
+ r128ctx->regs.sec_tex_offset[i] =
+ t->image[maxLevel-i].offset + (CARD32)t->bufAddr;
+ }
+ /* Fix AGP texture offsets */
+ if (t->heap == R128_AGP_TEX_HEAP)
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.sec_tex_offset[i] +=
+ R128_AGP_TEX_OFFSET + r128ctx->r128Screen->agpTexOffset;
+
+ /* Force loading the new state into the hardware */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_TEX1STATE | R128_CTX_ENGINESTATE;
+}
+
+/* Update the hardware texture state */
+/* NOTE: This function is only called while holding the hardware lock */
+void r128UpdateTextureState(r128ContextPtr r128ctx)
+{
+ /* Clear the GL_BLEND texturing fallback */
+ r128ctx->Fallback &= ~R128_FALLBACK_TEXTURE;
+
+ /* Unbind any currently bound textures */
+ if (r128ctx->CurrentTexObj[0]) r128ctx->CurrentTexObj[0]->bound = 0;
+ if (r128ctx->CurrentTexObj[1]) r128ctx->CurrentTexObj[1]->bound = 0;
+ r128ctx->CurrentTexObj[0] = NULL;
+ r128ctx->CurrentTexObj[1] = NULL;
+
+ /* Update the texture unit 0/1 state */
+ r128UpdateTex0State(r128ctx);
+ r128UpdateTex1State(r128ctx);
+}
+
+/* Set the texture wrap mode */
+static void r128SetTexWrap(r128TexObjPtr t, GLenum swrap, GLenum twrap)
+{
+ t->regs.tex_cntl &= ~(R128_TEX_CLAMP_S_MASK | R128_TEX_CLAMP_T_MASK);
+
+ switch (swrap) {
+ case GL_CLAMP: t->regs.tex_cntl |= R128_TEX_CLAMP_S_CLAMP; break;
+ case GL_REPEAT: t->regs.tex_cntl |= R128_TEX_CLAMP_S_WRAP; break;
+ default: /* ERROR!! */ return;
+ }
+
+ switch (twrap) {
+ case GL_CLAMP: t->regs.tex_cntl |= R128_TEX_CLAMP_T_CLAMP; break;
+ case GL_REPEAT: t->regs.tex_cntl |= R128_TEX_CLAMP_T_WRAP; break;
+ default: /* ERROR!! */ return;
+ }
+}
+
+/* Set the texture filter mode */
+static void r128SetTexFilter(r128TexObjPtr t, GLenum minf, GLenum magf)
+{
+ t->regs.tex_cntl &= ~(R128_MIN_BLEND_MASK | R128_MAG_BLEND_MASK);
+
+ switch (minf) {
+ case GL_NEAREST:
+ t->regs.tex_cntl |= R128_MIN_BLEND_NEAREST;
+ break;
+ case GL_LINEAR:
+ t->regs.tex_cntl |= R128_MIN_BLEND_LINEAR;
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ t->regs.tex_cntl |= R128_MIN_BLEND_MIPNEAREST;
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ t->regs.tex_cntl |= R128_MIN_BLEND_LINEARMIPNEAREST;
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ t->regs.tex_cntl |= R128_MIN_BLEND_MIPLINEAR;
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ t->regs.tex_cntl |= R128_MIN_BLEND_LINEARMIPLINEAR;
+ break;
+ default: /* ERROR!! */ return;
+ }
+
+ switch (magf) {
+ case GL_NEAREST:
+ t->regs.tex_cntl |= R128_MAG_BLEND_NEAREST;
+ break;
+ case GL_LINEAR:
+ t->regs.tex_cntl |= R128_MAG_BLEND_LINEAR;
+ break;
+ }
+}
+
+/* Set the texture border color */
+static void r128SetTexBorderColor(r128TexObjPtr t, GLubyte c[4])
+{
+ t->regs.border_color = r128PackColor(32, c[0], c[1], c[2], c[3]);
+}
+
+/* Set the texture environment state */
+static void r128DDTexEnv(GLcontext *ctx, GLenum target, GLenum pname,
+ const GLfloat *param)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit;
+ GLubyte c[4];
+ CARD32 col;
+
+ /* FIXME: Add texture LOD bias extension */
+
+ switch (pname) {
+ case GL_TEXTURE_ENV_MODE:
+ /* TexEnv modes are handled in UpdateTextureState */
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->dirty |= R128_UPDATE_TEXSTATE;
+ break;
+ case GL_TEXTURE_ENV_COLOR:
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ FLOAT_RGBA_TO_UBYTE_RGBA(texUnit->EnvColor, c);
+ col = r128PackColor(32, c[0], c[1], c[2], c[3]);
+ if (r128ctx->regs.constant_color_c != col) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.constant_color_c = col;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_TEXENVSTATE;
+ }
+ break;
+ default:
+ return;
+ }
+}
+
+/* Upload a new texture image */
+static void r128DDTexImage(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj, GLint level,
+ GLint internalFormat,
+ const struct gl_texture_image *image)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128TexObjPtr t;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API)
+ fprintf(stderr, "r128DDTexImage(%p, level %d)\n", tObj, level);
+
+ if ((target != GL_TEXTURE_2D) && (target != GL_TEXTURE_1D)) return;
+ if (level >= R128_TEX_MAXLEVELS) return;
+
+ t = (r128TexObjPtr)tObj->DriverData;
+ if (t) {
+ if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx);
+
+ /* Destroy the old texture, and upload a new one. The actual
+ uploading of the texture image occurs in the UploadSubImage
+ function. */
+ r128DestroyTexObj(r128ctx, t);
+ r128ctx->dirty |= R128_UPDATE_TEXSTATE;
+ }
+}
+
+/* Upload a new texture sub-image */
+static void r128DDTexSubImage(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLint internalFormat,
+ const struct gl_texture_image *image)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128TexObjPtr t;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API)
+ fprintf(stderr, "r128DDTexSubImage(%p, level %d) "
+ "size: %d,%d of %d,%d\n",
+ tObj, level, width, height, image->Width, image->Height);
+
+ if ((target != GL_TEXTURE_2D) && (target != GL_TEXTURE_1D)) return;
+ if (level >= R128_TEX_MAXLEVELS) return;
+
+ t = (r128TexObjPtr)tObj->DriverData;
+ if (t) {
+ if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx);
+
+ LOCK_HARDWARE(r128ctx);
+ r128UploadSubImage(r128ctx, t, level,
+ xoffset, yoffset, width, height);
+ UNLOCK_HARDWARE(r128ctx);
+
+ /* Update the context state */
+ r128ctx->regs.tex_cntl_c |= R128_TEX_CACHE_FLUSH;
+
+ r128ctx->dirty |= (R128_UPDATE_CONTEXT |
+ R128_UPDATE_TEXSTATE);
+ r128ctx->dirty_context |= (R128_CTX_ENGINESTATE |
+ R128_CTX_TEX0STATE |
+ R128_CTX_TEX1STATE);
+ }
+}
+
+/* Set the texture parameter state */
+static void r128DDTexParameter(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj,
+ GLenum pname, const GLfloat *params)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData;
+
+ if (!t) return;
+ if ((target != GL_TEXTURE_2D) && (target != GL_TEXTURE_1D)) return;
+
+ switch (pname) {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128SetTexFilter(t, tObj->MinFilter, tObj->MagFilter);
+ break;
+
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128SetTexWrap(t, tObj->WrapS, tObj->WrapT);
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128SetTexBorderColor(t, tObj->BorderColor);
+ break;
+
+ default:
+ return;
+ }
+
+ r128ctx->dirty |= R128_UPDATE_TEXSTATE;
+}
+
+/* Bind a texture to the currently active texture unit */
+static void r128DDBindTexture(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+
+ /* Unbind the old texture */
+ if (r128ctx->CurrentTexObj[ctx->Texture.CurrentUnit]) {
+ r128ctx->CurrentTexObj[ctx->Texture.CurrentUnit]->bound = 0;
+ r128ctx->CurrentTexObj[ctx->Texture.CurrentUnit] = NULL;
+ }
+
+ /* The actualy binding occurs in the Tex[01]UpdateState function */
+ r128ctx->dirty |= R128_UPDATE_TEXSTATE;
+}
+
+/* Remove texture from AGP/local texture memory */
+static void r128DDDeleteTexture(GLcontext *ctx,
+ struct gl_texture_object *tObj)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData;
+
+ if (t) {
+ if (t->bound) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+
+ r128ctx->CurrentTexObj[t->bound-1] = 0;
+ r128ctx->dirty |= R128_UPDATE_TEXSTATE;
+ }
+
+ r128DestroyTexObj(r128ctx, t);
+ tObj->DriverData = NULL;
+ }
+}
+
+/* Determine if a texture is currently residing in either AGP/local
+ texture memory */
+static GLboolean r128DDIsTextureResident(GLcontext *ctx,
+ struct gl_texture_object *tObj)
+{
+ r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData;
+
+ return t && t->memBlock;
+}
+
+/* Initialize the driver's texture functions */
+void r128DDInitTextureFuncs(GLcontext *ctx)
+{
+ ctx->Driver.TexEnv = r128DDTexEnv;
+ ctx->Driver.TexImage = r128DDTexImage;
+ ctx->Driver.TexSubImage = r128DDTexSubImage;
+ ctx->Driver.TexParameter = r128DDTexParameter;
+ ctx->Driver.BindTexture = r128DDBindTexture;
+ ctx->Driver.DeleteTexture = r128DDDeleteTexture;
+ ctx->Driver.UpdateTexturePalette = NULL;
+ ctx->Driver.ActiveTexture = NULL;
+ ctx->Driver.IsTextureResident = r128DDIsTextureResident;
+ ctx->Driver.PrioritizeTexture = NULL;
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.h b/xc/lib/GL/mesa/src/drv/r128/r128_tex.h
new file mode 100644
index 000000000..20893110c
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.h
@@ -0,0 +1,82 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Gareth Hughes <gareth@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_TEX_H_
+#define _R128_TEX_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void r128AgeTextures(r128ContextPtr r128ctx, int heap);
+extern int r128UploadTexImages(r128ContextPtr r128ctx, r128TexObjPtr t);
+extern void r128UpdateTextureState(r128ContextPtr r128ctx);
+extern void r128DestroyTexObj(r128ContextPtr r128ctx, r128TexObjPtr t);
+
+extern void r128DDInitTextureFuncs(GLcontext *ctx);
+
+#define R128PACKCOLOR332(r, g, b) \
+ (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6))
+
+#define R128PACKCOLOR1555(r, g, b, a) \
+ ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
+ ((a) ? 0x8000 : 0))
+
+#define R128PACKCOLOR565(r, g, b) \
+ ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
+
+#define R128PACKCOLOR888(r, g, b) \
+ (((r) << 16) | ((g) << 8) | (b))
+
+#define R128PACKCOLOR8888(r, g, b, a) \
+ (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+
+#define R128PACKCOLOR4444(r, g, b, a) \
+ ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
+
+static __inline__ CARD32 r128PackColor(GLuint depth,
+ GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a)
+{
+ switch (depth) {
+ case 8: return R128PACKCOLOR332(r, g, b);
+ case 15: return R128PACKCOLOR1555(r, g, b, a);
+ case 16: return R128PACKCOLOR565(r, g, b);
+ case 24: return R128PACKCOLOR888(r, g, b);
+ case 32: return R128PACKCOLOR8888(r, g, b, a);
+ default: return 0;
+ }
+}
+
+#endif
+#endif /* _R128_TEX_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h
new file mode 100644
index 000000000..588b768ed
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h
@@ -0,0 +1,87 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Gareth Hughes <gareth@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_TEXOBJ_H_
+#define _R128_TEXOBJ_H_
+
+#include "mm.h"
+
+#define R128_TEX_MAXLEVELS 11
+
+/* Setup registers for each texture */
+typedef struct {
+ CARD32 tex_cntl;
+ CARD32 size_pitch;
+ CARD32 border_color;
+} r128TextureRegs;
+
+/* Individual texture image information */
+typedef struct {
+ int offset; /* Offset into locally shared texture space (i.e.,
+ relative to bufAddr (below) */
+ int width; /* Width of texture image */
+ int height; /* Height of texture image */
+} r128TexImage;
+
+typedef struct r128_tex_obj r128TexObj, *r128TexObjPtr;
+
+/* Texture object in locally shared texture space */
+struct r128_tex_obj {
+ r128TexObjPtr next, prev;
+
+ struct gl_texture_object *tObj; /* Mesa texture object */
+
+ PMemBlock memBlock; /* Memory block containing texture */
+ unsigned char *bufAddr; /* Offset to start of locally
+ shared texture block */
+
+ CARD32 dirty_images; /* Flags for whether or not
+ images need to be uploaded to
+ local or AGP texture space */
+ int bound; /* Texture unit currently bound to */
+ int heap; /* Texture heap currently stored in */
+ r128TexImage image[R128_TEX_MAXLEVELS]; /* Image data for all
+ mipmap levels */
+ int totalSize; /* Total size of the texture
+ including all mipmap levels */
+ int internFormat; /* Internal GL format used to store
+ texture on card */
+ int textureFormat; /* Actual hardware format */
+ int texelBytes; /* Number of bytes per texel */
+
+ r128TextureRegs regs; /* Setup regs for texture */
+};
+
+#endif /* _R128_TEXOBJ_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c
new file mode 100644
index 000000000..1c1b45daf
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c
@@ -0,0 +1,548 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+#include "r128_vb.h"
+#include "r128_tris.h"
+#include "r128_state.h"
+
+static triangle_func tri_tab[0x40]; /* only 0x20 actually used */
+static quad_func quad_tab[0x40]; /* only 0x20 actually used */
+static line_func line_tab[0x40]; /* less than 0x20 used */
+static points_func points_tab[0x40]; /* less than 0x20 used */
+
+/* Draw a triangle from the vertices in the vertex buffer */
+void r128DrawTriangleVB(r128ContextPtr r128ctx,
+ r128_vertex *v0,
+ r128_vertex *v1,
+ r128_vertex *v2)
+{
+ r128_vertex *vbptr;
+
+ if (r128ctx->disableVB) {
+ r128DrawTriangle(r128ctx, v0, v1, v2);
+ return;
+ }
+
+ R128CCE_ALLOC_VB_SPACE(r128ctx, vbptr, 3);
+
+ *vbptr++ = *v0;
+ *vbptr++ = *v1;
+ *vbptr++ = *v2;
+}
+
+/* Draw a triangle */
+void r128DrawTriangle(r128ContextPtr r128ctx,
+ r128_vertex *v0,
+ r128_vertex *v1,
+ r128_vertex *v2)
+{
+ LOCK_HARDWARE(r128ctx);
+ BEGIN_CLIP_LOOP(r128ctx);
+
+#if USE_RHW2
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 34);
+#else
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 31);
+#endif
+ R128CCE(R128_FULL_VERTEX_FORMAT);
+ R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST |
+ R128_CCE_VC_CNTL_PRIM_WALK_RING |
+ (3 << R128_CCE_VC_CNTL_NUM_SHIFT));
+
+ R128CCE_SEND_VERTEX(v0);
+ R128CCE_SEND_VERTEX(v1);
+ R128CCE_SEND_VERTEX(v2);
+
+ R128CCE_SUBMIT_PACKETS();
+
+ END_CLIP_LOOP(r128ctx);
+ UNLOCK_HARDWARE(r128ctx);
+}
+
+/* Draw a line from the vertices in the vertex buffer */
+void r128DrawLineVB(r128ContextPtr r128ctx,
+ r128_vertex *v0, r128_vertex *v1,
+ float width)
+{
+ float dx, dy, ix, iy;
+ r128_vertex *vbptr;
+
+ /* FIXME: Use r128's line primitive for width 1 lines */
+ if (r128ctx->disableVB) {
+ r128DrawLine(r128ctx, v0, v1, width);
+ return;
+ }
+
+ R128CCE_ALLOC_VB_SPACE(r128ctx, vbptr, 3);
+
+ dx = v0->x - v1->x;
+ dy = v0->y - v1->y;
+
+ ix = width * 0.5; iy = 0;
+ if (dx*dx > dy*dy) {
+ iy = ix; ix = 0;
+ }
+
+ *vbptr = *v0; vbptr->x = v0->x - ix; vbptr->y = v0->y - iy;
+ *++vbptr = *v1; vbptr->x = v1->x + ix; vbptr->y = v1->y + iy;
+ *++vbptr = *v0; vbptr->x = v0->x + ix; vbptr->y = v0->y + iy;
+ *++vbptr = *v0; vbptr->x = v0->x - ix; vbptr->y = v0->y - iy;
+ *++vbptr = *v1; vbptr->x = v1->x - ix; vbptr->y = v1->y - iy;
+ *++vbptr = *v1; vbptr->x = v1->x + ix; vbptr->y = v1->y + iy;
+}
+
+/* Draw a line */
+void r128DrawLine(r128ContextPtr r128ctx,
+ r128_vertex *v0, r128_vertex *v1,
+ float width)
+{
+ LOCK_HARDWARE(r128ctx);
+ if (width != 1) {
+ float dx, dy, ix, iy;
+
+ dx = v0->x - v1->x;
+ dy = v0->y - v1->y;
+
+ ix = width * 0.5; iy = 0;
+ if (dx*dx > dy*dy) {
+ iy = ix; ix = 0;
+ }
+
+ BEGIN_CLIP_LOOP(r128ctx);
+
+#if USE_RHW2
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 67);
+#else
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 61);
+#endif
+ R128CCE(R128_FULL_VERTEX_FORMAT);
+ R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST |
+ R128_CCE_VC_CNTL_PRIM_WALK_RING |
+ (6 << R128_CCE_VC_CNTL_NUM_SHIFT));
+
+ R128CCEF(v0->x - ix);
+ R128CCEF(v0->y - iy);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v1->x + ix);
+ R128CCEF(v1->y + iy);
+ R128CCEF(v1->z);
+ R128CCEF(v1->rhw);
+ R128CCE(*(int *)&v1->dif_argb);
+ R128CCE(*(int *)&v1->spec_frgb);
+ R128CCEF(v1->tu0);
+ R128CCEF(v1->tv0);
+ R128CCEF(v1->tu1);
+ R128CCEF(v1->tv1);
+#if USE_RHW2
+ R128CCEF(v1->rhw2);
+#endif
+
+ R128CCEF(v0->x + ix);
+ R128CCEF(v0->y + iy);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v0->x - ix);
+ R128CCEF(v0->y - iy);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v1->x - ix);
+ R128CCEF(v1->y - iy);
+ R128CCEF(v1->z);
+ R128CCEF(v1->rhw);
+ R128CCE(*(int *)&v1->dif_argb);
+ R128CCE(*(int *)&v1->spec_frgb);
+ R128CCEF(v1->tu0);
+ R128CCEF(v1->tv0);
+ R128CCEF(v1->tu1);
+ R128CCEF(v1->tv1);
+#if USE_RHW2
+ R128CCEF(v1->rhw2);
+#endif
+
+ R128CCEF(v1->x + ix);
+ R128CCEF(v1->y + iy);
+ R128CCEF(v1->z);
+ R128CCEF(v1->rhw);
+ R128CCE(*(int *)&v1->dif_argb);
+ R128CCE(*(int *)&v1->spec_frgb);
+ R128CCEF(v1->tu0);
+ R128CCEF(v1->tv0);
+ R128CCEF(v1->tu1);
+ R128CCEF(v1->tv1);
+#if USE_RHW2
+ R128CCEF(v1->rhw2);
+#endif
+
+ R128CCE_SUBMIT_PACKETS();
+
+ END_CLIP_LOOP(r128ctx);
+ } else {
+ BEGIN_CLIP_LOOP(r128ctx);
+
+#if USE_RHW2
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 23);
+#else
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 21);
+#endif
+ R128CCE(R128_FULL_VERTEX_FORMAT);
+ R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_LINE |
+ R128_CCE_VC_CNTL_PRIM_WALK_RING |
+ (2 << R128_CCE_VC_CNTL_NUM_SHIFT));
+
+ R128CCE_SEND_VERTEX(v0);
+ R128CCE_SEND_VERTEX(v1);
+
+ R128CCE_SUBMIT_PACKETS();
+
+ END_CLIP_LOOP(r128ctx);
+ }
+ UNLOCK_HARDWARE(r128ctx);
+}
+
+/* Draw a point from the vertices in the vertex buffer */
+void r128DrawPointVB(r128ContextPtr r128ctx,
+ r128_vertex *v0, float size)
+{
+ r128_vertex *vbptr;
+
+ /* FIXME: Use r128's point primitive for diameter 1 points */
+ if (r128ctx->disableVB) {
+ r128DrawPoint(r128ctx, v0, size);
+ return;
+ }
+
+ R128CCE_ALLOC_VB_SPACE(r128ctx, vbptr, 3);
+
+ *vbptr = *v0; vbptr->x = v0->x - size; vbptr->y = v0->y - size;
+ *++vbptr = *v0; vbptr->x = v0->x + size; vbptr->y = v0->y - size;
+ *++vbptr = *v0; vbptr->x = v0->x + size; vbptr->y = v0->y + size;
+ *++vbptr = *v0; vbptr->x = v0->x + size; vbptr->y = v0->y + size;
+ *++vbptr = *v0; vbptr->x = v0->x - size; vbptr->y = v0->y + size;
+ *++vbptr = *v0; vbptr->x = v0->x - size; vbptr->y = v0->y - size;
+}
+
+/* Draw a point */
+void r128DrawPoint(r128ContextPtr r128ctx,
+ r128_vertex *v0, float size)
+{
+ LOCK_HARDWARE(r128ctx);
+ if (size != 0.5) {
+ BEGIN_CLIP_LOOP(r128ctx);
+
+#if USE_RHW2
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 67);
+#else
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 61);
+#endif
+ R128CCE(R128_FULL_VERTEX_FORMAT);
+ R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST |
+ R128_CCE_VC_CNTL_PRIM_WALK_RING |
+ (6 << R128_CCE_VC_CNTL_NUM_SHIFT));
+
+ R128CCEF(v0->x - size);
+ R128CCEF(v0->y - size);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v0->x + size);
+ R128CCEF(v0->y - size);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v0->x + size);
+ R128CCEF(v0->y + size);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v0->x + size);
+ R128CCEF(v0->y + size);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v0->x - size);
+ R128CCEF(v0->y + size);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v0->x - size);
+ R128CCEF(v0->y - size);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCE_SUBMIT_PACKETS();
+
+ END_CLIP_LOOP(r128ctx);
+ } else {
+ BEGIN_CLIP_LOOP(r128ctx);
+
+#if USE_RHW2
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 12);
+#else
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 11);
+#endif
+ R128CCE(R128_FULL_VERTEX_FORMAT);
+ R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_POINT |
+ R128_CCE_VC_CNTL_PRIM_WALK_RING |
+ (1 << R128_CCE_VC_CNTL_NUM_SHIFT));
+
+ R128CCE_SEND_VERTEX(v0);
+
+ R128CCE_SUBMIT_PACKETS();
+
+ END_CLIP_LOOP(r128ctx);
+ }
+ UNLOCK_HARDWARE(r128ctx);
+}
+
+#define R128_COLOR(to, from) \
+do { \
+ (to)[0] = (from)[2]; \
+ (to)[1] = (from)[1]; \
+ (to)[2] = (from)[0]; \
+ (to)[3] = (from)[3]; \
+} while (0)
+
+#define IND (0)
+#define TAG(x) x
+#include "r128_tritmp.h"
+
+#define IND (R128_FLAT_BIT)
+#define TAG(x) x##_flat
+#include "r128_tritmp.h"
+
+#define IND (R128_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "r128_tritmp.h"
+
+#define IND (R128_OFFSET_BIT | R128_FLAT_BIT)
+#define TAG(x) x##_offset_flat
+#include "r128_tritmp.h"
+
+#define IND (R128_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "r128_tritmp.h"
+
+#define IND (R128_TWOSIDE_BIT | R128_FLAT_BIT)
+#define TAG(x) x##_twoside_flat
+#include "r128_tritmp.h"
+
+#define IND (R128_TWOSIDE_BIT | R128_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "r128_tritmp.h"
+
+#define IND (R128_TWOSIDE_BIT | R128_OFFSET_BIT | R128_FLAT_BIT)
+#define TAG(x) x##_twoside_offset_flat
+#include "r128_tritmp.h"
+
+/* Initialize the table of points, line and triangle drawing functions */
+void r128TriangleFuncsInit(void)
+{
+ init();
+ init_flat();
+ init_offset();
+ init_offset_flat();
+ init_twoside();
+ init_twoside_flat();
+ init_twoside_offset();
+ init_twoside_offset_flat();
+}
+
+/* Setup the Point, Line, Triangle and Quad functions based on the
+ current rendering state. Wherever possible, use the hardware to
+ render the primitive. Otherwise, fallback to software rendering. */
+void r128ChooseRenderState(GLcontext *ctx)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ GLuint flags = ctx->TriangleCaps;
+
+ if (r128ctx->Fallback) return;
+
+ if (r128ctx->SWonly) {
+ r128ctx->IndirectTriangles = DD_SW_RASTERIZE;
+ r128ctx->PointsFunc = NULL;
+ r128ctx->LineFunc = NULL;
+ r128ctx->TriangleFunc = NULL;
+ r128ctx->QuadFunc = NULL;
+ return;
+ } else {
+ r128ctx->IndirectTriangles = 0;
+ }
+
+ if (flags) {
+ CARD32 index = 0;
+ CARD32 shared = 0;
+ CARD32 fallback = R128_FALLBACK_BIT;
+
+ if (r128ctx->SWfallbackDisable) fallback = 0; /* No fallbacks */
+ if (r128ctx->SWonly) shared = fallback; /* Everything's a fallback */
+
+ if (flags & DD_FLATSHADE) shared |= R128_FLAT_BIT;
+ if (flags & DD_MULTIDRAW) shared |= fallback;
+ if (flags & DD_SELECT) shared |= R128_FALLBACK_BIT;
+ if (flags & DD_FEEDBACK) shared |= R128_FALLBACK_BIT;
+
+ /* Setup PointFunc */
+ index = shared;
+ if (flags & DD_POINT_SMOOTH) index |= fallback;
+ if (flags & DD_POINT_ATTEN) index |= fallback;
+
+ r128ctx->RenderIndex = index;
+ r128ctx->PointsFunc = points_tab[index];
+ if (index & R128_FALLBACK_BIT)
+ r128ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE;
+
+ /* Setup LineFunc */
+ index = shared;
+ if (flags & DD_LINE_SMOOTH) index |= fallback;
+ if (flags & DD_LINE_STIPPLE) index |= fallback;
+
+ r128ctx->RenderIndex |= index;
+ r128ctx->LineFunc = line_tab[index];
+ if (index & R128_FALLBACK_BIT)
+ r128ctx->IndirectTriangles |= DD_LINE_SW_RASTERIZE;
+
+ /* Setup TriangleFunc and QuadFunc */
+ index = shared;
+ if (flags & DD_TRI_SMOOTH) index |= fallback;
+ if (flags & DD_TRI_OFFSET) index |= R128_OFFSET_BIT;
+ if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R128_TWOSIDE_BIT;
+ if (flags & DD_TRI_UNFILLED) index |= fallback;
+ if (flags & DD_TRI_STIPPLE) index |= fallback;
+
+ r128ctx->RenderIndex |= index;
+ r128ctx->TriangleFunc = tri_tab[index];
+ r128ctx->QuadFunc = quad_tab[index];
+ if (index & R128_FALLBACK_BIT)
+ r128ctx->IndirectTriangles |= (DD_TRI_SW_RASTERIZE |
+ DD_QUAD_SW_RASTERIZE);
+ } else if (r128ctx->RenderIndex) {
+ r128ctx->RenderIndex = 0;
+ r128ctx->PointsFunc = points_tab[0];
+ r128ctx->LineFunc = line_tab[0];
+ r128ctx->TriangleFunc = tri_tab[0];
+ r128ctx->QuadFunc = quad_tab[0];
+ }
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h
new file mode 100644
index 000000000..0980f2791
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h
@@ -0,0 +1,76 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_TRIS_H_
+#define _R128_TRIS_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "r128_vb.h"
+
+#define R128_ANTIALIAS_BIT 0x00 /* ignored for now, no fallback */
+#define R128_FLAT_BIT 0x01
+#define R128_OFFSET_BIT 0x02
+#define R128_TWOSIDE_BIT 0x04
+#define R128_NODRAW_BIT 0x08
+#define R128_FALLBACK_BIT 0x10
+#define R128_FEEDBACK_BIT 0x20
+#define R128_SELECT_BIT 0x40
+#define R128_POINT_PARAM_BIT 0x80 /* not needed? */
+
+extern void r128DrawTriangleVB(r128ContextPtr r128ctx,
+ r128_vertex *v0,
+ r128_vertex *v1,
+ r128_vertex *v2);
+extern void r128DrawLineVB(r128ContextPtr r128ctx,
+ r128_vertex *tmp0, r128_vertex *tmp1,
+ float width);
+extern void r128DrawPointVB(r128ContextPtr r128ctx,
+ r128_vertex *tmp, float size);
+
+extern void r128DrawTriangle(r128ContextPtr r128ctx,
+ r128_vertex *v0,
+ r128_vertex *v1,
+ r128_vertex *v2);
+extern void r128DrawLine(r128ContextPtr r128ctx,
+ r128_vertex *tmp0, r128_vertex *tmp1,
+ float width);
+extern void r128DrawPoint(r128ContextPtr r128ctx,
+ r128_vertex *tmp, float size);
+
+extern void r128ChooseRenderState(GLcontext *ctx);
+extern void r128TriangleFuncsInit(void);
+
+#endif
+#endif /* _R128_TRIS_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h b/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h
new file mode 100644
index 000000000..833bd832a
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h
@@ -0,0 +1,327 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#if !defined(TAG) || !defined(IND)
+ this is an error
+#endif
+
+/* Draw a single triangle. Note that the device-dependent vertex data
+ might need to be changed based on the render state. */
+static void TAG(triangle)(GLcontext *ctx,
+ GLuint e0, GLuint e1, GLuint e2,
+ GLuint pv)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ struct vertex_buffer *VB = ctx->VB;
+ r128VertexPtr r128verts = R128_DRIVER_DATA(VB)->verts;
+ const r128_vertex *v0 = &r128verts[e0].v;
+ const r128_vertex *v1 = &r128verts[e1].v;
+ const r128_vertex *v2 = &r128verts[e2].v;
+
+#if (IND & R128_OFFSET_BIT)
+ GLfloat offset;
+#endif
+
+#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
+ int c0 = *(int *)&r128verts[pv].v.dif_argb;
+ int c1 = c0;
+ int c2 = c0;
+#endif
+
+#if (IND & R128_OFFSET_BIT)
+ switch (ctx->Visual->DepthBits) {
+ case 16: offset = ctx->Polygon.OffsetUnits / 65536.0; break;
+ case 24: offset = ctx->Polygon.OffsetUnits / 16777216.0; break;
+ case 32: offset = ctx->Polygon.OffsetUnits / 4294967296.0; break;
+ default: offset = ctx->Polygon.OffsetUnits / 65536.0; break;
+ }
+#endif
+
+#if (IND & (R128_TWOSIDE_BIT | R128_OFFSET_BIT))
+ {
+ GLfloat ex = v0->x - v2->x;
+ GLfloat ey = v0->y - v2->y;
+ GLfloat fx = v1->x - v2->x;
+ GLfloat fy = v1->y - v2->y;
+ GLfloat c = ex*fy - ey*fx;
+
+#if (IND & R128_TWOSIDE_BIT)
+ {
+ GLuint facing = (c > 0.0) ^ ctx->Polygon.FrontBit;
+ GLubyte (*vbcolor)[4] = VB->Color[facing]->data;
+ if (IND & R128_FLAT_BIT) {
+ R128_COLOR((char *)&c0, vbcolor[pv]);
+ c2 = c1 = c0;
+ } else {
+ R128_COLOR((char *)&c0, vbcolor[e0]);
+ R128_COLOR((char *)&c1, vbcolor[e1]);
+ R128_COLOR((char *)&c2, vbcolor[e2]);
+ }
+ }
+#endif
+
+#if (IND & R128_OFFSET_BIT)
+ {
+ if (c * c > 1e-16) {
+ GLfloat factor = ctx->Polygon.OffsetFactor;
+ GLfloat ez = v0->z - v2->z;
+ GLfloat fz = v1->z - v2->z;
+ GLfloat a = ey*fz - ez*fy;
+ GLfloat b = ez*fx - ex*fz;
+ GLfloat ic = 1.0 / c;
+ GLfloat ac = a * ic;
+ GLfloat bc = b * ic;
+ if (ac < 0.0f) ac = -ac;
+ if (bc < 0.0f) bc = -bc;
+ offset += MAX2(ac, bc) * factor;
+ }
+ }
+#endif
+ }
+#endif
+
+ LOCK_HARDWARE(r128ctx);
+ if (r128ctx->regs.tex_cntl_c & (R128_TEXMAP_ENABLE |
+ R128_SEC_TEXMAP_ENABLE)) {
+ BEGIN_CLIP_LOOP(r128ctx);
+
+#if USE_RHW2
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 34);
+#else
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 31);
+#endif
+ R128CCE(R128_FULL_VERTEX_FORMAT);
+ R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST |
+ R128_CCE_VC_CNTL_PRIM_WALK_RING |
+ (3 << R128_CCE_VC_CNTL_NUM_SHIFT));
+
+ R128CCEF(v0->x);
+ R128CCEF(v0->y);
+#if (IND & R128_OFFSET_BIT)
+ R128CCEF(v0->z + offset);
+#else
+ R128CCEF(v0->z);
+#endif
+ R128CCEF(v0->rhw);
+
+#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
+ R128CCE(c0);
+#else
+ R128CCE(*(int *)&v0->dif_argb);
+#endif
+ R128CCE(*(int *)&v0->spec_frgb);
+
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v1->x);
+ R128CCEF(v1->y);
+#if (IND & R128_OFFSET_BIT)
+ R128CCEF(v1->z + offset);
+#else
+ R128CCEF(v1->z);
+#endif
+ R128CCEF(v1->rhw);
+
+#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
+ R128CCE(c1);
+#else
+ R128CCE(*(int *)&v1->dif_argb);
+#endif
+ R128CCE(*(int *)&v1->spec_frgb);
+
+ R128CCEF(v1->tu0);
+ R128CCEF(v1->tv0);
+ R128CCEF(v1->tu1);
+ R128CCEF(v1->tv1);
+#if USE_RHW2
+ R128CCEF(v1->rhw2);
+#endif
+
+ R128CCEF(v2->x);
+ R128CCEF(v2->y);
+#if (IND & R128_OFFSET_BIT)
+ R128CCEF(v2->z + offset);
+#else
+ R128CCEF(v2->z);
+#endif
+ R128CCEF(v2->rhw);
+
+#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
+ R128CCE(c2);
+#else
+ R128CCE(*(int *)&v2->dif_argb);
+#endif
+ R128CCE(*(int *)&v2->spec_frgb);
+
+ R128CCEF(v2->tu0);
+ R128CCEF(v2->tv0);
+ R128CCEF(v2->tu1);
+ R128CCEF(v2->tv1);
+#if USE_RHW2
+ R128CCEF(v2->rhw2);
+#endif
+
+ R128CCE_SUBMIT_PACKETS();
+
+ END_CLIP_LOOP(r128ctx);
+ } else {
+ BEGIN_CLIP_LOOP(r128ctx);
+
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 13);
+ R128CCE(R128_CCE_VC_FRMT_DIFFUSE_ARGB);
+ R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST |
+ R128_CCE_VC_CNTL_PRIM_WALK_RING |
+ (3 << R128_CCE_VC_CNTL_NUM_SHIFT));
+
+ R128CCEF(v0->x);
+ R128CCEF(v0->y);
+#if (IND & R128_OFFSET_BIT)
+ R128CCEF(v0->z + offset);
+#else
+ R128CCEF(v0->z);
+#endif
+
+#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
+ R128CCE(c0);
+#else
+ R128CCE(*(int *)&v0->dif_argb);
+#endif
+
+ R128CCEF(v1->x);
+ R128CCEF(v1->y);
+#if (IND & R128_OFFSET_BIT)
+ R128CCEF(v1->z + offset);
+#else
+ R128CCEF(v1->z);
+#endif
+
+#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
+ R128CCE(c1);
+#else
+ R128CCE(*(int *)&v1->dif_argb);
+#endif
+
+ R128CCEF(v2->x);
+ R128CCEF(v2->y);
+#if (IND & R128_OFFSET_BIT)
+ R128CCEF(v2->z + offset);
+#else
+ R128CCEF(v2->z);
+#endif
+
+#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
+ R128CCE(c2);
+#else
+ R128CCE(*(int *)&v2->dif_argb);
+#endif
+
+ R128CCE_SUBMIT_PACKETS();
+
+ END_CLIP_LOOP(r128ctx);
+ }
+ UNLOCK_HARDWARE(r128ctx);
+}
+
+static void TAG(quad)(GLcontext *ctx,
+ GLuint v0, GLuint v1, GLuint v2, GLuint v3,
+ GLuint pv)
+{
+ TAG(triangle)(ctx, v0, v1, v3, pv);
+ TAG(triangle)(ctx, v1, v2, v3, pv);
+}
+
+#if ((IND & ~R128_FLAT_BIT) == 0)
+
+/* Draw a single line. Note that the device-dependent vertex data might
+ need to be changed based on the render state. */
+static void TAG(line)(GLcontext *ctx,
+ GLuint v0, GLuint v1,
+ GLuint pv)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128VertexPtr r128verts = R128_DRIVER_DATA(ctx->VB)->verts;
+ r128_vertex tmp0 = r128verts[v0].v;
+ r128_vertex tmp1 = r128verts[v1].v;
+ float width = ctx->Line.Width;
+
+ if (IND & R128_FLAT_BIT) {
+ *(int *)&tmp1.dif_argb =
+ *(int *)&tmp0.dif_argb =
+ *(int *)&r128verts[pv].v.dif_argb;
+ }
+
+ r128DrawLine(r128ctx, &tmp0, &tmp1, width);
+}
+
+/* Draw a set of points. Note that the device-dependent vertex data
+ might need to be changed based on the render state. */
+static void TAG(points)(GLcontext *ctx,
+ GLuint first, GLuint last)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ struct vertex_buffer *VB = ctx->VB;
+ r128VertexPtr r128verts = R128_DRIVER_DATA(VB)->verts;
+ GLfloat size = ctx->Point.Size * 0.5;
+ int i;
+
+ for(i = first; i <= last; i++) {
+ if(VB->ClipMask[i] == 0) {
+ r128_vertex *tmp = &r128verts[i].v;
+ r128DrawPoint(r128ctx, tmp, size);
+ }
+ }
+}
+
+#endif
+
+/* Initialize the table of primitives to render. */
+static void TAG(init)(void)
+{
+ tri_tab[IND] = TAG(triangle);
+ quad_tab[IND] = TAG(quad);
+
+#if ((IND & ~R128_FLAT_BIT) == 0)
+ line_tab[IND] = TAG(line);
+ points_tab[IND] = TAG(points);
+#endif
+}
+
+#undef IND
+#undef TAG
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c
new file mode 100644
index 000000000..f14ec21bd
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c
@@ -0,0 +1,470 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+#include "r128_state.h"
+#include "r128_vb.h"
+
+#include "stages.h"
+
+#define TEX0 \
+do { \
+ v->v.tu0 = tc0[i][0]; \
+ v->v.tv0 = tc0[i][1]; \
+} while (0)
+
+#define TEX1 \
+do { \
+ v->v.tu1 = tc1[i][0]; \
+ v->v.tv1 = tc1[i][1]; \
+} while (0)
+
+#define SPC \
+do { \
+ GLubyte *spec = &(VB->Spec[0][i][0]); \
+ v->v.spec_frgb.r = spec[0]; \
+ v->v.spec_frgb.g = spec[1]; \
+ v->v.spec_frgb.b = spec[2]; \
+} while (0)
+
+#define FOG \
+do { \
+ GLubyte *spec = &(VB->Spec[0][i][0]); \
+ v->v.spec_frgb.a = spec[3]; \
+} while (0)
+
+#define COL \
+do { \
+ GLubyte *col = &(VB->Color[0]->data[i][0]); \
+ v->v.dif_argb.a = col[3]; \
+ v->v.dif_argb.r = col[0]; \
+ v->v.dif_argb.g = col[1]; \
+ v->v.dif_argb.b = col[2]; \
+} while (0)
+
+#if 1
+/* FIXME: These are handled by the Rage 128 */
+#define TEX0_4
+#define TEX1_4
+#else
+#define TEX0_4 \
+do { \
+ if (VB->TexCoordPtr[0]->size == 4) { \
+ GLfloat (*tc)[4] = VB->TexCoordPtr[0]->data; \
+ v = &(R128_DRIVER_DATA(VB)->verts[start]); \
+ for (i = start; i < end; i++, v++) { \
+ float oow = 1.0 / tc[i][3]; \
+ v->v.rhw *= tc[i][3]; \
+ v->v.tu0 *= oow; \
+ v->v.tv0 *= oow; \
+ } \
+ } \
+} while (0)
+
+#if USE_RHW2
+#define TEX1_4 \
+do { \
+ if (VB->TexCoordPtr[1]->size == 4) { \
+ GLfloat (*tc)[4] = VB->TexCoordPtr[1]->data; \
+ v = &(R128_DRIVER_DATA(VB)->verts[start]); \
+ for (i = start; i < end; i++, v++) { \
+ float oow = 1.0 / tc[i][3]; \
+ v->v.rhw2 *= tc[i][3]; \
+ v->v.tu1 *= oow; \
+ v->v.tv1 *= oow; \
+ } \
+ } \
+} while (0)
+#else
+#define TEX1_4
+#endif
+#endif
+
+#if USE_RHW2
+#define COORD \
+do { \
+ GLfloat *win = VB->Win.data[i]; \
+ v->v.x = win[0]; \
+ v->v.y = r128height - win[1]; \
+ v->v.z = scale * win[2]; \
+ v->v.rhw = v->v.rhw2 = win[3]; \
+} while (0)
+#else
+#define COORD \
+do { \
+ GLfloat *win = VB->Win.data[i]; \
+ v->v.x = win[0]; \
+ v->v.y = r128height - win[1]; \
+ v->v.z = scale * win[2]; \
+ v->v.rhw = win[3]; \
+} while (0)
+#endif
+
+#define NOP
+
+/* Setup the r128 vertex buffer entries */
+#define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,tex1_4,spec,fog) \
+static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \
+{ \
+ r128ContextPtr r128ctx = R128_CONTEXT(VB->ctx); \
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \
+ r128VertexPtr v; \
+ GLfloat (*tc0)[4]; \
+ GLfloat (*tc1)[4]; \
+ GLfloat r128height = dPriv->h; \
+ GLfloat scale; \
+ int i; \
+ \
+ (void) r128height; (void) r128ctx; \
+ \
+ gl_import_client_data(VB, VB->ctx->RenderFlags, \
+ (VB->ClipOrMask \
+ ? VEC_WRITABLE | VEC_GOOD_STRIDE \
+ : VEC_GOOD_STRIDE)); \
+ \
+ switch (VB->ctx->Visual->DepthBits) { \
+ case 16: scale = 1.0 / 65536.0; break; \
+ case 24: scale = 1.0 / 16777216.0; break; \
+ case 32: scale = 1.0 / 4294967296.0; break; \
+ default: scale = 1.0 / 65536.0; break; \
+ } \
+ \
+ tc0 = VB->TexCoordPtr[0]->data; \
+ tc1 = VB->TexCoordPtr[1]->data; \
+ \
+ v = &(R128_DRIVER_DATA(VB)->verts[start]); \
+ \
+ if (VB->ClipOrMask == 0) \
+ for (i = start; i < end; i++, v++) { \
+ win; \
+ col; \
+ spec; \
+ fog; \
+ tex0; \
+ tex1; \
+ } \
+ else \
+ for (i = start; i < end; i++, v++) { \
+ if (VB->ClipMask[i] == 0) { \
+ win; \
+ spec; \
+ fog; \
+ tex0; \
+ tex1; \
+ } \
+ col; \
+ } \
+ tex0_4; \
+ tex1_4; \
+}
+
+
+SETUPFUNC(rs_wt0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, NOP, NOP)
+SETUPFUNC(rs_wt1, COORD, NOP, NOP, TEX1, NOP, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_wt0t1, COORD, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_wft0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, NOP, FOG)
+SETUPFUNC(rs_wft1, COORD, NOP, NOP, TEX1, NOP, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_wft0t1, COORD, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_wg, COORD, COL, NOP, NOP, NOP, NOP, NOP, NOP)
+SETUPFUNC(rs_wgs, COORD, COL, NOP, NOP, NOP, NOP, SPC, NOP)
+SETUPFUNC(rs_wgt0, COORD, COL, TEX0, NOP, TEX0_4, NOP, NOP, NOP)
+SETUPFUNC(rs_wgt1, COORD, COL, NOP, TEX1, NOP, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_wgt0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_wgst0, COORD, COL, TEX0, NOP, TEX0_4, NOP, SPC, NOP)
+SETUPFUNC(rs_wgst1, COORD, COL, NOP, TEX1, NOP, TEX1_4, SPC, NOP)
+SETUPFUNC(rs_wgst0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, NOP)
+SETUPFUNC(rs_wgf, COORD, COL, NOP, NOP, NOP, NOP, NOP, FOG)
+SETUPFUNC(rs_wgfs, COORD, COL, NOP, NOP, NOP, NOP, SPC, FOG)
+SETUPFUNC(rs_wgft0, COORD, COL, TEX0, NOP, TEX0_4, NOP, NOP, FOG)
+SETUPFUNC(rs_wgft1, COORD, COL, NOP, TEX1, NOP, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_wgft0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_wgfst0, COORD, COL, TEX0, NOP, TEX0_4, NOP, SPC, FOG)
+SETUPFUNC(rs_wgfst1 , COORD, COL, NOP, TEX1, NOP, TEX1_4, SPC, FOG)
+SETUPFUNC(rs_wgfst0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, FOG)
+
+SETUPFUNC(rs_t0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, NOP, NOP)
+SETUPFUNC(rs_t1, NOP, NOP, NOP, TEX1, NOP, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_t0t1, NOP, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_f, NOP, NOP, NOP, NOP, NOP, NOP, NOP, FOG)
+SETUPFUNC(rs_ft0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, NOP, FOG)
+SETUPFUNC(rs_ft1, NOP, NOP, NOP, TEX1, NOP, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_ft0t1, NOP, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_g, NOP, COL, NOP, NOP, NOP, NOP, NOP, NOP)
+SETUPFUNC(rs_gs, NOP, COL, NOP, NOP, NOP, NOP, SPC, NOP)
+SETUPFUNC(rs_gt0, NOP, COL, TEX0, NOP, TEX0_4, NOP, NOP, NOP)
+SETUPFUNC(rs_gt1, NOP, COL, NOP, TEX1, NOP, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_gt0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_gst0, NOP, COL, TEX0, NOP, TEX0_4, NOP, SPC, NOP)
+SETUPFUNC(rs_gst1, NOP, COL, NOP, TEX1, NOP, TEX1_4, SPC, NOP)
+SETUPFUNC(rs_gst0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, NOP)
+SETUPFUNC(rs_gf, NOP, COL, NOP, NOP, NOP, NOP, NOP, FOG)
+SETUPFUNC(rs_gfs, NOP, COL, NOP, NOP, NOP, NOP, SPC, FOG)
+SETUPFUNC(rs_gft0, NOP, COL, TEX0, NOP, TEX0_4, NOP, NOP, FOG)
+SETUPFUNC(rs_gft1, NOP, COL, NOP, TEX1, NOP, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_gft0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_gfst0, NOP, COL, TEX0, NOP, TEX0_4, NOP, SPC, FOG)
+SETUPFUNC(rs_gfst1, NOP, COL, NOP, TEX1, NOP, TEX1_4, SPC, FOG)
+SETUPFUNC(rs_gfst0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, FOG)
+
+static void rs_invalid(struct vertex_buffer *VB, GLuint start, GLuint end)
+{
+ fprintf(stderr, "r128RasterSetup(): invalid setup function\n");
+}
+
+typedef void (*setupFunc)(struct vertex_buffer *, GLuint, GLuint);
+static setupFunc setup_func[0x80];
+
+/* Initialize the table of vertex buffer setup functions */
+void r128SetupInit(void)
+{
+ int i;
+
+ for (i = 0; i < 0x80; i++) setup_func[i] = rs_invalid;
+
+ /* Funcs to build vertices from scratch */
+ setup_func[R128_WIN_BIT|R128_TEX0_BIT] = rs_wt0;
+ setup_func[R128_WIN_BIT|R128_TEX1_BIT] = rs_wt1;
+ setup_func[R128_WIN_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wt0t1;
+ setup_func[R128_WIN_BIT|R128_FOG_BIT|R128_TEX0_BIT] = rs_wft0;
+ setup_func[R128_WIN_BIT|R128_FOG_BIT|R128_TEX1_BIT] = rs_wft1;
+ setup_func[R128_WIN_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wft0t1;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT] = rs_wg;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT] = rs_wgs;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_TEX0_BIT] = rs_wgt0;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_TEX1_BIT] = rs_wgt1;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgt0t1;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_wgst0;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX1_BIT] = rs_wgst1;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgst0t1;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT] = rs_wgf;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT] = rs_wgfs;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT] = rs_wgft0;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX1_BIT] = rs_wgft1;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgft0t1;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_wgfst0;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX1_BIT] = rs_wgfst1;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgfst0t1;
+
+ /* Funcs to repair vertices */
+ setup_func[R128_TEX0_BIT] = rs_t0;
+ setup_func[R128_TEX1_BIT] = rs_t1;
+ setup_func[R128_TEX0_BIT|R128_TEX1_BIT] = rs_t0t1;
+ setup_func[R128_FOG_BIT] = rs_f;
+ setup_func[R128_FOG_BIT|R128_TEX0_BIT] = rs_ft0;
+ setup_func[R128_FOG_BIT|R128_TEX1_BIT] = rs_ft1;
+ setup_func[R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_ft0t1;
+ setup_func[R128_RGBA_BIT] = rs_g;
+ setup_func[R128_RGBA_BIT|R128_SPEC_BIT] = rs_gs;
+ setup_func[R128_RGBA_BIT|R128_TEX0_BIT] = rs_gt0;
+ setup_func[R128_RGBA_BIT|R128_TEX1_BIT] = rs_gt1;
+ setup_func[R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gt0t1;
+ setup_func[R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_gst0;
+ setup_func[R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX1_BIT] = rs_gst1;
+ setup_func[R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gst0t1;
+ setup_func[R128_RGBA_BIT|R128_FOG_BIT] = rs_gf;
+ setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT] = rs_gfs;
+ setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT] = rs_gft0;
+ setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_TEX1_BIT] = rs_gft1;
+ setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gft0t1;
+ setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_gfst0;
+ setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX1_BIT] = rs_gfst1;
+ setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gfst0t1;
+}
+
+/* Initialize the vertex buffer setup functions based on the current
+ rendering state */
+void r128ChooseRasterSetupFunc(GLcontext *ctx)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ int funcIndex = R128_WIN_BIT | R128_RGBA_BIT;
+
+ if (ctx->Texture.Enabled & 0xf) {
+ if (ctx->Texture.Unit[0].EnvMode == GL_REPLACE)
+ funcIndex &= ~R128_RGBA_BIT;
+ funcIndex |= R128_TEX0_BIT;
+ }
+
+ if (ctx->Texture.Enabled & 0xf0)
+ funcIndex |= R128_TEX1_BIT;
+
+ /* FIXME: Verify this works properly */
+ if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
+ funcIndex |= R128_SPEC_BIT;
+
+ if (ctx->FogMode == FOG_FRAGMENT)
+ funcIndex |= R128_FOG_BIT;
+
+ r128ctx->SetupIndex = funcIndex;
+ ctx->Driver.RasterSetup = setup_func[funcIndex];
+}
+
+/* Check to see if any updates of the vertex buffer entries are needed */
+void r128CheckPartialRasterSetup(GLcontext *ctx,
+ struct gl_pipeline_stage *s)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ int tmp = r128ctx->SetupDone;
+
+ s->type = 0;
+ r128ctx->SetupDone = GL_FALSE;
+
+ if ((ctx->Array.Summary & VERT_OBJ_ANY) == 0) return;
+ if (ctx->IndirectTriangles) return;
+
+ r128ctx->SetupDone = tmp;
+}
+
+/* Update the vertex buffer entries, if necessary */
+void r128PartialRasterSetup(struct vertex_buffer *VB)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(VB->ctx);
+ int new = VB->pipeline->new_outputs;
+ int available = VB->pipeline->outputs;
+ int index = 0;
+
+ if (new & VERT_WIN) {
+ new = available;
+ index |= R128_WIN_BIT | R128_FOG_BIT;
+ }
+
+ if (new & VERT_RGBA) index |= R128_RGBA_BIT | R128_SPEC_BIT;
+ if (new & VERT_TEX0_ANY) index |= R128_TEX0_BIT;
+ if (new & VERT_TEX1_ANY) index |= R128_TEX1_BIT;
+#if 0
+ /* FIXME */
+ if (new & VERT_FOG_COORD) index |= R128_FOG_BIT;
+#endif
+
+ r128ctx->SetupDone &= ~index;
+ index &= r128ctx->SetupIndex;
+ r128ctx->SetupDone |= index;
+
+ if (index) setup_func[index & ~R128_ALPHA_BIT](VB, VB->Start, VB->Count);
+}
+
+/* Perform the raster setup for the fast path, if using CVA */
+void r128DoRasterSetup(struct vertex_buffer *VB)
+{
+ GLcontext *ctx = VB->ctx;
+
+ if (VB->Type == VB_CVA_PRECALC) r128PartialRasterSetup(VB);
+ else if (ctx->Driver.RasterSetup) ctx->Driver.RasterSetup(VB,
+ VB->CopyStart,
+ VB->Count);
+}
+
+/* Resize an existing vertex buffer */
+void r128ResizeVB(struct vertex_buffer *VB, GLuint size)
+{
+ r128VertexBufferPtr r128vb = R128_DRIVER_DATA(VB);
+
+ while (r128vb->size < size)
+ r128vb->size *= 2;
+
+ free(r128vb->vert_store);
+ r128vb->vert_store = malloc(sizeof(r128Vertex) * r128vb->size + 31);
+ if (!r128vb->vert_store) {
+ fprintf(stderr, "Cannot allocate vertex store! Exiting...\n");
+ exit(1);
+ }
+
+ r128vb->verts = (r128VertexPtr)(((CARD32)r128vb->vert_store + 31) & ~31);
+
+ gl_vector1ui_free(&r128vb->clipped_elements);
+ gl_vector1ui_alloc(&r128vb->clipped_elements,
+ VEC_WRITABLE, r128vb->size, 32);
+ if (!r128vb->clipped_elements.start) {
+ fprintf(stderr, "Cannot allocate clipped elements! Exiting...\n");
+ exit(1);
+ }
+
+ free(VB->ClipMask);
+ VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * r128vb->size);
+ if (!VB->ClipMask) {
+ fprintf(stderr, "Cannot allocate clipmask! Exiting...\n");
+ exit(1);
+ }
+}
+
+/* Create a new device-dependent vertex buffer */
+void r128DDRegisterVB(struct vertex_buffer *VB)
+{
+ r128VertexBufferPtr r128vb;
+
+ r128vb = (r128VertexBufferPtr)calloc(1, sizeof(*r128vb));
+
+ r128vb->size = VB->Size * 2;
+ r128vb->vert_store = malloc(sizeof(r128Vertex) * r128vb->size + 31);
+ if (!r128vb->vert_store) {
+ fprintf(stderr, "Cannot allocate vertex store! Exiting...\n");
+ exit(1);
+ }
+
+ r128vb->verts = (r128VertexPtr)(((CARD32)r128vb->vert_store + 31) & ~31);
+
+ gl_vector1ui_alloc(&r128vb->clipped_elements,
+ VEC_WRITABLE, r128vb->size, 32);
+ if (!r128vb->clipped_elements.start) {
+ fprintf(stderr, "Cannot allocate clipped elements! Exiting...\n");
+ exit(1);
+ }
+
+ free(VB->ClipMask);
+ VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * r128vb->size);
+ if (!VB->ClipMask) {
+ fprintf(stderr, "Cannot allocate clipmask! Exiting...\n");
+ exit(1);
+ }
+
+ VB->driver_data = r128vb;
+}
+
+/* Destroy a device-dependent vertex buffer */
+void r128DDUnregisterVB(struct vertex_buffer *VB)
+{
+ r128VertexBufferPtr r128vb = R128_DRIVER_DATA(VB);
+
+ if (r128vb) {
+ if (r128vb->vert_store) free(r128vb->vert_store);
+ gl_vector1ui_free(&r128vb->clipped_elements);
+ free(r128vb);
+ VB->driver_data = 0;
+ }
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h
new file mode 100644
index 000000000..4f7c11d7f
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h
@@ -0,0 +1,150 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_VB_H_
+#define _R128_VB_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#define USE_RHW2 0
+
+/* FIXME: This is endian-specific */
+typedef struct {
+ GLubyte b;
+ GLubyte g;
+ GLubyte r;
+ GLubyte a;
+} r128Color;
+
+typedef struct {
+ GLfloat x, y, z; /* Coordinates in screen space */
+ GLfloat rhw; /* Reciprocal homogeneous w */
+ r128Color dif_argb; /* Diffuse color */
+ r128Color spec_frgb; /* Specular color (alpha is fog) */
+ GLfloat tu0, tv0; /* Texture 0 coordinates */
+ GLfloat tu1, tv1; /* Texture 1 coordinates */
+#if USE_RHW2
+ GLfloat rhw2; /* Reciprocal homogeneous w */
+#endif
+} r128_vertex;
+
+#if USE_RHW2
+/* Format of vertices in r128_vertex struct */
+#define R128_FULL_VERTEX_FORMAT \
+ R128_CCE_VC_FRMT_RHW | \
+ R128_CCE_VC_FRMT_DIFFUSE_ARGB | \
+ R128_CCE_VC_FRMT_SPEC_FRGB | \
+ R128_CCE_VC_FRMT_S_T | \
+ R128_CCE_VC_FRMT_S2_T2 | \
+ R128_CCE_VC_FRMT_RHW2
+
+/* Send a single vertex to the ring buffer */
+#define R128CCE_SEND_VERTEX(v) \
+ do { \
+ R128CCEF((v)->x); \
+ R128CCEF((v)->y); \
+ R128CCEF((v)->z); \
+ R128CCEF((v)->rhw); \
+ R128CCE(*(int *)&(v)->dif_argb); \
+ R128CCE(*(int *)&(v)->spec_frgb); \
+ R128CCEF((v)->tu0); \
+ R128CCEF((v)->tv0); \
+ R128CCEF((v)->tu1); \
+ R128CCEF((v)->tv1); \
+ R128CCEF((v)->rhw2); \
+ } while (0)
+
+#else /* !USE_RHW2 */
+
+/* Format of vertices in r128_vertex struct */
+#define R128_FULL_VERTEX_FORMAT \
+ R128_CCE_VC_FRMT_RHW | \
+ R128_CCE_VC_FRMT_DIFFUSE_ARGB | \
+ R128_CCE_VC_FRMT_SPEC_FRGB | \
+ R128_CCE_VC_FRMT_S_T | \
+ R128_CCE_VC_FRMT_S2_T2
+
+/* Send a single vertex to the ring buffer */
+#define R128CCE_SEND_VERTEX(v) \
+ do { \
+ R128CCEF((v)->x); \
+ R128CCEF((v)->y); \
+ R128CCEF((v)->z); \
+ R128CCEF((v)->rhw); \
+ R128CCE(*(int *)&(v)->dif_argb); \
+ R128CCE(*(int *)&(v)->spec_frgb); \
+ R128CCEF((v)->tu0); \
+ R128CCEF((v)->tv0); \
+ R128CCEF((v)->tu1); \
+ R128CCEF((v)->tv1); \
+ } while (0)
+#endif
+
+/* FIXME: We currently only have assembly for 16-stride vertices */
+typedef union {
+ r128_vertex v;
+ float f[16];
+} r128Vertex, *r128VertexPtr;
+
+/* Vertex buffer for use when on the fast path */
+typedef struct {
+ GLuint size; /* Number of vertices in store */
+ void *vert_store; /* Storage for vertex buffer */
+ r128VertexPtr verts; /* Aligned start of verts in storage */
+ int last_vert; /* Index of last vertex used */
+ GLvector1ui clipped_elements; /* List of clipped elements */
+} *r128VertexBufferPtr;
+
+#define R128_DRIVER_DATA(vb) ((r128VertexBufferPtr)((vb)->driver_data))
+
+#define R128_SPEC_BIT 0x01
+#define R128_FOG_BIT 0x02
+#define R128_ALPHA_BIT 0x04 /* GL_BLEND, not used */
+#define R128_TEX1_BIT 0x08
+#define R128_TEX0_BIT 0x10
+#define R128_RGBA_BIT 0x20
+#define R128_WIN_BIT 0x40
+
+extern void r128SetupInit(void);
+extern void r128ChooseRasterSetupFunc(GLcontext *ctx);
+extern void r128CheckPartialRasterSetup(GLcontext *ctx,
+ struct gl_pipeline_stage *s);
+extern void r128PartialRasterSetup(struct vertex_buffer *VB);
+extern void r128DoRasterSetup(struct vertex_buffer *VB);
+extern void r128ResizeVB(struct vertex_buffer *VB, GLuint size);
+extern void r128DDRegisterVB(struct vertex_buffer *VB);
+extern void r128DDUnregisterVB(struct vertex_buffer *VB);
+
+#endif
+#endif /* _R128_VB_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c
new file mode 100644
index 000000000..60d528813
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c
@@ -0,0 +1,257 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifdef GLX_DIRECT_RENDERING
+
+/* r128 Mesa driver includes */
+#include "r128_init.h"
+#include "r128_context.h"
+#include "r128_xmesa.h"
+#include "r128_state.h"
+#include "r128_tex.h"
+#include "r128_swap.h"
+
+/* Mesa src includes */
+#include "context.h"
+#include "simple_list.h"
+#include "mmath.h"
+
+#ifndef R128_DEBUG_FLAGS
+int R128_DEBUG_FLAGS = (0
+#if 0
+ | DEBUG_ALWAYS_SYNC
+ | DEBUG_VERBOSE_CCE
+ | DEBUG_VERBOSE_OUTREG
+ | DEBUG_VERBOSE_MSG
+ | DEBUG_NO_OUTRING
+ | DEBUG_NO_OUTREG
+ | DEBUG_VERBOSE_API
+ | DEBUG_VERBOSE_2D
+ | DEBUG_VERBOSE_DRI
+ | DEBUG_VALIDATE_RING
+ | DEBUG_VERBOSE_IOCTL
+#endif
+ );
+#endif
+
+#if DEBUG_LOCKING
+char *prevLockFile = NULL;
+int prevLockLine = 0;
+#endif
+
+static r128ContextPtr r128Context = NULL;
+
+
+/* Initialize the driver specific screen private data */
+GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
+{
+ sPriv->private = (void *)r128CreateScreen(sPriv);
+ if (!sPriv->private) {
+ r128DestroyScreen(sPriv);
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+/* Reset the driver specific screen private data */
+void XMesaResetDriver(__DRIscreenPrivate *sPriv)
+{
+ r128DestroyScreen(sPriv);
+}
+
+/* Create and initialize the Mesa and driver specific visual data */
+GLvisual *XMesaCreateVisual(Display *dpy,
+ __DRIscreenPrivate *driScrnPriv,
+ const XVisualInfo *visinfo,
+ const __GLXvisualConfig *config)
+{
+ /* Drivers may change the args to _mesa_create_visual() in order to
+ * setup special visuals.
+ */
+ return _mesa_create_visual(config->rgba,
+ config->doubleBuffer,
+ config->stereo,
+ _mesa_bitcount(visinfo->red_mask),
+ _mesa_bitcount(visinfo->green_mask),
+ _mesa_bitcount(visinfo->blue_mask),
+ config->alphaSize,
+ 0, /* index bits */
+ config->depthSize,
+ config->stencilSize,
+ config->accumRedSize,
+ config->accumGreenSize,
+ config->accumBlueSize,
+ config->accumAlphaSize,
+ 0 /* num samples */);
+}
+
+/* Create and initialize the Mesa and driver specific context data */
+GLboolean XMesaCreateContext(Display *dpy, GLvisual *mesaVis,
+ __DRIcontextPrivate *driContextPriv)
+{
+ return r128CreateContext(dpy, mesaVis, driContextPriv);
+}
+
+/* Destroy the Mesa and driver specific context data */
+void XMesaDestroyContext(__DRIcontextPrivate *driContextPriv)
+{
+ r128ContextPtr r128ctx = (r128ContextPtr)driContextPriv->driverPrivate;
+
+ if (r128ctx == (void *)r128Context) r128Context = NULL;
+ r128DestroyContext(r128ctx);
+}
+
+/* Create and initialize the Mesa and driver specific pixmap buffer data */
+GLframebuffer *XMesaCreateWindowBuffer(Display *dpy,
+ __DRIscreenPrivate *driScrnPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ GLvisual *mesaVis)
+{
+ return gl_create_framebuffer(mesaVis,
+ GL_FALSE, /* software depth buffer? */
+ mesaVis->StencilBits > 0,
+ mesaVis->AccumRedBits > 0,
+ mesaVis->AlphaBits > 0
+ );
+}
+
+/* Create and initialize the Mesa and driver specific pixmap buffer data */
+GLframebuffer *XMesaCreatePixmapBuffer( Display *dpy,
+ __DRIscreenPrivate *driScrnPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ GLvisual *mesaVis)
+{
+#if 0
+ /* Different drivers may have different combinations of hardware and
+ * software ancillary buffers.
+ */
+ return gl_create_framebuffer(mesaVis,
+ GL_FALSE, /* software depth buffer? */
+ mesaVis->StencilBits > 0,
+ mesaVis->AccumRedBits > 0,
+ mesaVis->AlphaBits > 0);
+#else
+ return NULL; /* not implemented yet */
+#endif
+}
+
+/* Copy the back color buffer to the front color buffer */
+void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv)
+{
+ /* FIXME: This assumes buffer is currently bound to a context. This
+ needs to be able to swap buffers when not currently bound. Also,
+ this needs to swap according to buffer, and NOT according to
+ context! */
+ if (r128Context == NULL) return;
+
+ /* Only swap buffers when a back buffer exists */
+ if (R128_MESACTX(r128Context)->Visual->DBflag) {
+ FLUSH_VB(R128_MESACTX(r128Context), "swap buffers");
+ r128SwapBuffers(r128Context);
+ }
+}
+
+/* Force the context `c' to be the current context and associate with it
+ buffer `b' */
+GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv)
+{
+ if (driContextPriv) {
+ r128ContextPtr r128ctx = (r128ContextPtr)driContextPriv->driverPrivate;
+
+ if (r128Context &&
+ r128ctx == (void *)r128Context &&
+ driDrawPriv == R128_DRIDRAWABLE(r128Context))
+ return GL_TRUE;
+
+ r128Context = r128MakeCurrent(r128Context, r128ctx, driDrawPriv);
+
+ gl_make_current2(R128_MESACTX(r128Context),
+ driDrawPriv->mesaBuffer, driReadPriv->mesaBuffer);
+
+ if (!R128_MESACTX(r128Context)->Viewport.Width) {
+ gl_Viewport(R128_MESACTX(r128Context), 0, 0,
+ driDrawPriv->w, driDrawPriv->h);
+ }
+ } else {
+ gl_make_current(0,0);
+ r128Context = NULL;
+ }
+
+ return GL_TRUE;
+}
+
+/* Force the context `c' to be unbound from its buffer */
+GLboolean XMesaUnbindContext(__DRIcontextPrivate *driContextPriv)
+{
+ return GL_TRUE;
+}
+
+/* Update the hardware state. This is called if another context has
+ grabbed the hardware lock, which includes the X server. This
+ function also updates the driver's window state after the X server
+ moves, resizes or restacks a window -- the change will be reflected
+ in the drawable position and clip rects. Since the X server grabs
+ the hardware lock when it changes the window state, this routine will
+ automatically be called after such a change. */
+/* NOTE: This routine is only called while holding the hardware lock. */
+void XMesaUpdateState(__DRIcontextPrivate *driContextPriv)
+{
+ r128ContextPtr r128ctx = driContextPriv->driverPrivate;
+ __DRIscreenPrivate *sPriv = R128_DRISCREEN(r128ctx);
+ __DRIdrawablePrivate *dPriv = R128_DRIDRAWABLE(r128ctx);
+ int stamp = dPriv->lastStamp;
+
+ /* The window might have moved, so we might need to get new clip
+ rects.
+
+ NOTE: This releases and regrabs the hw lock to allow the X server
+ to respond to the DRI protocol request for new drawable info.
+ Since the hardware state depends on having the latest drawable
+ clip rects, all state checking must be done _after_ this call. */
+ XMESA_VALIDATE_DRAWABLE_INFO(r128ctx->display, sPriv, dPriv);
+
+ r128UpdateState(r128ctx, (stamp != dPriv->lastStamp));
+}
+
+/* This function is called by libGL.so as soon as libGL.so is loaded.
+ * This is where we'd register new extension functions with the dispatcher.
+ */
+void __driRegisterExtensions(void)
+{
+}
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.h b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.h
new file mode 100644
index 000000000..ca6fc127b
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.h
@@ -0,0 +1,44 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_XMESA_H_
+#define _R128_XMESA_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void XMesaUpdateState(__DRIcontextPrivate *driContextPriv);
+extern void __driRegisterExtensions(void);
+
+#endif
+#endif /* _R128_XMESA_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile
index c159a8e76..4a6a8e0ff 100644
--- a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile
@@ -79,7 +79,8 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX)
fxglidew.o fxpipeline.o fxrender.o fxsanity.o fxsetup.o \
fxtexman.o fxtrifuncs.o fxvsetup.o
- MESASRCS = ../../accum.c \
+ MESASRCS = ../../aatriangle.c \
+ ../../accum.c \
../../alpha.c \
../../alphabuf.c \
../../attrib.c \
@@ -109,7 +110,7 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX)
../../glthread.c \
../../hash.c \
../../image.c \
- ../../imaging.o \
+ ../../imaging.c \
../../light.c \
../../lines.c \
../../logic.c \
@@ -120,6 +121,7 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX)
../../pb.c \
../../pipeline.c \
../../pixel.c \
+ ../../pixeltex.c \
../../points.c \
../../polygon.c \
../../quads.c \
@@ -136,6 +138,7 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX)
../../texobj.c \
../../texstate.c \
../../texture.c \
+ ../../texutil.c \
../../translate.c \
../../triangle.c \
../../varray.c \
@@ -152,7 +155,8 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX)
../../zoom.c \
../../X86/common_x86.c
- MESAOBJS = ../../accum.o \
+ MESAOBJS = ../../aatriangle.o \
+ ../../accum.o \
../../alpha.o \
../../alphabuf.o \
../../attrib.o \
@@ -191,6 +195,7 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX)
../../pb.o \
../../pipeline.o \
../../pixel.o \
+ ../../pixeltex.o \
../../points.o \
../../polygon.o \
../../quads.o \
@@ -207,6 +212,7 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX)
../../texobj.o \
../../texstate.o \
../../texture.o \
+ ../../texutil.o \
../../translate.o \
../../triangle.o \
../../varray.o \
@@ -239,8 +245,7 @@ LinkSourceFile(fxvs_tmp.h, ../../../../../../extras/Mesa/src/FX)
MMX_OBJS = ../../X86/mmx_blend.o
-XCOMM Disabling 3Dnow code for the time being.
-#if 0
+#if MesaUse3DNow
3DNOW_SRCS = ../../X86/3dnow.c \
../../X86/3dnow_norm_raw.S \
../../X86/3dnow_xform_masked1.S \
@@ -271,10 +276,14 @@ XCOMM Disabling 3Dnow code for the time being.
ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS)
ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS)
- SRCS = $(DRISRCS) $(DRMSRCS) $(TDFXSRCS) $(MESASRCS) $(ASMSRCS)
- OBJS = $(DRIOBJS) $(DRMOBJS) $(TDFXOBJS) $(MESAOBJS) $(ASMOBJS)
+ SRCS = $(DRISRCS) $(DRMSRCS) $(TDFXSRCS) $(MESASRCS) $(ASMSRCS)
+ OBJS = $(DRIOBJS) $(DRMOBJS) $(TDFXOBJS) $(MESAOBJS) $(ASMOBJS)
+
+REQUIREDLIBS = -lglide3x -lm
+#if !GlxBuiltInTdfx
+REQUIREDLIBS += -L../../../.. -lGL
+#endif
-REQUIREDLIBS += -lglide3x
#if !GlxUseBuiltInDRIDriver
#undef DoNormalLib NormalLibGlx
diff --git a/xc/programs/Xserver/GL/dri/dri.c b/xc/programs/Xserver/GL/dri/dri.c
index 0bff80a6c..c48c156bd 100644
--- a/xc/programs/Xserver/GL/dri/dri.c
+++ b/xc/programs/Xserver/GL/dri/dri.c
@@ -112,7 +112,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
fd = drmOpen(pDRIInfo->drmDriverName, NULL);
if (fd < 0) {
/* failed to open DRM */
- pScreen->devPrivates[DRIScreenPrivIndex].ptr = 0;
+ pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
return FALSE;
}
@@ -125,7 +125,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
pDRIPriv = (DRIScreenPrivPtr) xalloc(sizeof(DRIScreenPrivRec));
if (!pDRIPriv) {
- pScreen->devPrivates[DRIScreenPrivIndex].ptr = 0;
+ pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
return FALSE;
}
@@ -137,6 +137,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
if (drmSetBusid(pDRIPriv->drmFD, pDRIPriv->pDriverInfo->busIdString) < 0) {
pDRIPriv->directRenderingSupport = FALSE;
+ pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
drmClose(pDRIPriv->drmFD);
return FALSE;
}
@@ -155,6 +156,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
&pDRIPriv->hSAREA) < 0)
{
pDRIPriv->directRenderingSupport = FALSE;
+ pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
drmClose(pDRIPriv->drmFD);
return FALSE;
}
@@ -168,6 +170,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
(drmAddressPtr)(&pDRIPriv->pSAREA)) < 0)
{
pDRIPriv->directRenderingSupport = FALSE;
+ pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
drmClose(pDRIPriv->drmFD);
return FALSE;
}
@@ -182,6 +185,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
&pDRIPriv->hFrameBuffer) < 0)
{
pDRIPriv->directRenderingSupport = FALSE;
+ pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
drmUnmap(pDRIPriv->pSAREA, pDRIPriv->pDriverInfo->SAREASize);
drmClose(pDRIPriv->drmFD);
return FALSE;
diff --git a/xc/programs/Xserver/Imakefile b/xc/programs/Xserver/Imakefile
index c1e91e6c5..cf9770537 100644
--- a/xc/programs/Xserver/Imakefile
+++ b/xc/programs/Xserver/Imakefile
@@ -619,7 +619,7 @@ XF86IDRVOBJS = $(XF86SRC)/input/drvConf.o
XF86IDRVLIBS = $(XF86IDRIVERLIB)
XF86SCANLIB = $(XF86SRC)/scanpci/LibraryTargetName(scanpci)
XF86LIBS = $(XF86INIT) $(XF86COMLIB) $(XF86RACLIB) $(XF86PARSLIB) \
- $(XF86OSLIB) $(XF86INT10LIB)
+ $(XF86OSLIB) $(XF86INT10LIB) $(XF86DDCLIB)
#else
XF86LIBS = $(XF86INIT) $(XF86COMLIB) $(XF86PARSLIB) $(XF86OSLIB)
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml
index 895ce09a7..e95ff113a 100644
--- a/xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml
@@ -3,17 +3,17 @@
]>
<!-- Created: Mon Feb 28 13:00:00 2000 by brian@precisioninsight.com -->
-<!-- Revised: Mon Mar 6 20:10:02 2000 by kevin@precisioninsight.com -->
+<!-- Revised: Fri May 19 09:41:48 2000 by martin@valinux.com -->
<article>
- <title>DRI Users Guide
+ <title>DRI User Guide
<author><htmlurl url="http://www.precisioninsight.com/"
name="Precision Insight, Inc.">
- <date>6 March 2000
+ <date>18 May 2000
<ident>
- $XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml,v 1.3 2000/03/08 05:38:41 dawes Exp $
+ $XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml,v 1.3 2000/04/05 05:38:41 brianp Exp $
</ident>
<toc>
@@ -25,7 +25,7 @@
<bf>Copyright &copy; 2000 by Precision Insight, Inc.,
Cedar Park, Texas.
All Rights Reserved.</bf>
- <p>
+<p>
<bf>Permission is granted to make and distribute verbatim copies
of this document provided the copyright notice and this permission
notice are preserved on all copies.</bf>
@@ -43,6 +43,8 @@
trademarks of 3Dlabs Inc. Ltd.
3dfx, Voodoo3, Voodoo4, and Voodoo5 are registered trademarks of
3dfx Interactive, Incorporated.
+ Matrox is a registered trademark of Matrox Electronic Systems Ltd.
+ ATI Rage is a registered trademark of ATI Technologies, Inc.
All other trademarks mentioned are the property of their
respective owners.
@@ -60,9 +62,13 @@
software downloads.
<p>
This document does not cover compilation or installation of
- XFree86 4.0;
- it is assumed that you've already installed a Linux distribution which
- includes XFree86 4.0.
+ XFree86 4.0.
+ It is assumed that you've already installed a Linux distribution which
+ includes XFree86 4.0 or that you're an experienced Linux developer
+ who has compiled the DRI for himself.
+ DRI download, compilation and installation instructions can be found
+ at <htmlurl url="http://dri.sourceforge.net/DRIcompile.html"
+ name="http://dri.sourceforge.net/DRIcompile.html">
<sect>Supported Hardware
<p>
@@ -71,8 +77,8 @@
Support for Alpha, and perhaps other CPUs, should be available in the
future.
<p>
- XFree86 4.0 includes 3D acceleration for the following
- graphics hardware:
+ XFree86 4.0 (or later versions) includes 3D acceleration for the
+ following graphics hardware:
<itemize>
<item>3dfx:
@@ -87,6 +93,19 @@
</itemize>
There are many configurations of 3dfx cards on the market.
Not all have been tested.
+ <item>Matrox G400
+ <item>ATI Rage 128
+ <itemize>
+ <item>Rage Fury AGP
+ <item>Rage Magnum AGP
+ <item>XPERT 2000 AGP
+ <item>XPERT 128 AGP
+ <item>XPERT 99 AGP
+ <item>All-in-Wonder 128 AGP
+ </itemize>
+ The PCI versions of these cards also have minimal support.
+ Note that there are also Rage 128 Pro based boards on the
+ market, and these are not yet supported.
<item>3Dlabs Oxygen GMX 2000 (MX/Gamma based)
</itemize>
@@ -94,8 +113,6 @@
Support for the following hardware is underway:
<itemize>
<item>Intel i810
- <item>Matrox G400
- <item>ATI Rage 128
<item>3dfx Voodoo4 and Voodoo5 series
</itemize>
@@ -104,8 +121,10 @@
<p>
<itemize>
<item>XFree86 4.0
- <item>Linux kernel 2.2.x (later kernels will be supported in
+ <item>For the 3dfx Voodoo3 driver, Linux kernel 2.2.x (later
+ kernels will be supported in
the near future, and may be required for some chipsets)
+ <item>For the Matrox G400, Linux kernel 2.3.51, with AGP support
</itemize>
<p>
Mesa 3.3 (beta) is included with XFree86 4.0; there is no need to
@@ -119,20 +138,17 @@
<sect1>Kernel module
<p>
- Before starting the X server you must install the correct kernel
- module for your hardware.
- <p>
- This can be done by executing the following as root:
- <verb>
- insmod XXX/drivername.o
- </verb>
- <p>
- For example, on 3dfx hardware, the kernel module is called tdfx.o
- so you you would type insmod XXX/tdfx.o
-
- <p>
- Verify that the kernel module was installed by checking that
- /proc/dri/0 exists.
+ XFree86 4.0.1 added automatic kernel module loading to the X server.
+ On Linux, the X server uses modprobe to load kernel modules.
+ The DRM kernel modules should be in /lib/modules/KERNEL-VERSION/misc/
+ for automatic loading to work.
+<p>
+ Optionally, DRM kernel modules can be loaded manually with insmod
+ prior to starting the X server.
+<p>
+ You can verify that the kernel module was installed with lsmod,
+ checking the X server startup log, and checking that /proc/dri/0
+ exists.
<sect1>XF86Config file
<p>
@@ -199,6 +215,7 @@
<p>
Next, the Device section of the XF86Config file must describe your
particular hardware.
+ <p>
For example, here's the Device section for a 3dfx Voodoo3 card:
<verb>
@@ -210,6 +227,27 @@
</verb>
<p>
+ Here's the Device section for a Matrox G400 card:
+ <verb>
+ Section "Device"
+ Identifier "G400"
+ VendorName "Matrox"
+ Driver "mga"
+ VideoRam 32768
+ EndSection
+ </verb>
+
+ <p>
+ Here's the Device section for an ATI Rage 128 card:
+ <verb>
+ Section "Device"
+ Identifier "Rage128"
+ VendorName "ATI"
+ Driver "r128"
+ EndSection
+ </verb>
+
+ <p>
Finally, the Screen section of the XF86Config file may have to be
specially configured as well.
For example, Voodoo3 hardware acceleration is only available
@@ -227,7 +265,10 @@
EndSubsection
EndSection
</verb>
-
+ <p>
+ Replace <em>Voodoo3</em> with <em>G400</em> for Matrox G400.
+ <p>
+ Replace <em>Voodoo3</em> with <em>Rage128</em> for ATI Rage 128.
<p>
If there are errors in the XF86Config file, the X server will
log errors to the file /var/log/XFree86.0.log
@@ -301,6 +342,25 @@
if means that the libGL.so.1 file is not the right location.
Proceed to the trouble shooting section.
+ <sect1>libOSMesa.so
+<p>
+ OSMesa (Off-Screen Mesa) is an interface and driver for rendering
+ 3D images into a user-allocated block of memory rather than an
+ on-screen window.
+<p>
+ libOSMesa.so implements the OSMesa interface and must be linked
+ with your application if you want to use the OSMesa functions.
+ You must also link with libGL.so. For example:
+ <verb>
+ gcc osdemo.c -L/usr/X11R6/lib -lOSMesa -lGLU -lGL -o osdemo
+ </verb>
+<p>
+ In stand-alone Mesa this interface was compiled into the monolithic
+ libGL.so (formerly libMesaGL.so) library.
+ In XFree86 4.0.1 and later this interface is implemented in a
+ separate library.
+<p>
+
<sect1>glxinfo
<p>
glxinfo is a useful program for checking which version of
@@ -346,20 +406,25 @@
<enum>
<item>
<tt/LIBGL_DEBUG/, if defined will cause libGL.so to print error
- and diagnostic messages. This can help to solve problems.
+ and diagnostic messages.
+ This can help to solve problems.
+ Setting <tt/LIBGL_DEBUG/ to <tt/verbose/ may provide additional
+ information.
<item>
<tt/LIBGL_ALWAYS_INDIRECT/, if defined this will force libGL.so
to always use indirect rendering instead of hardware
- acceleration.
+ acceleration.
This can be useful to isolate rendering errors.
<item>
- <tt/LIBGL_DRIVERS_DIR/ can be used to override the default
- directory which is searched for 3D drivers.
+ <tt/LIBGL_DRIVERS_PATH/ can be used to override the default
+ directories which are searched for 3D drivers.
+ The value is one or more paths separated by colons.
In a typical XFree86 installation, the 3D drivers should be in
- /usr/X11R6/lib/modules/dri/.
- This environment variable can be used to specify a different
- directory.
+ /usr/X11R6/lib/modules/dri/ and <tt/LIBGL_DRIVERS_PATH/ need
+ not be defined.
Note that this feature is disabled for set-uid programs.
+ This variable replaces the <tt/LIBGL_DRIVERS_DIR/ env var used
+ in XFree86 4.0.
</enum>
<p>
Mesa-based drivers (this includes most of the drivers listed
@@ -531,6 +596,40 @@
<sect1>3dfx Voodoo3
<p>
+ <sect2>Configuration
+<p>
+ Your XF86Config file's device section must specify the
+ <tt>tdfx</tt> device:
+ <verb>
+ Section "Device"
+ Identifier "Voodoo3"
+ VendorName "3dfx"
+ Driver "tdfx"
+ EndSection
+ </verb>
+ The Screen section should then reference the Voodoo3 device:
+ <verb>
+ Section "Screen"
+ Identifier "Screen 1"
+ Device "Voodoo3"
+ Monitor "High Res Monitor"
+ DefaultDepth 16
+ Subsection "Display"
+ Depth 16
+ Modes "1280x1024" "1024x768" "800x600" "640x480"
+ ViewPort 0 0
+ EndSubsection
+ EndSection
+ </verb>
+ <p>
+ The kernel module for the Voodoo3 is named <tt>tdfx.o</tt> and
+ should be installed in /lib/modules/KERNEL-VERSION/misc/.
+ It will be automatically loaded by the Xserver if needed.
+ <p>
+ The DRI 3D driver for the Voodoo3 should be in
+ <tt>/usr/X11R6/lib/modules/dri/tdfx_dri.so</tt>.
+ This will be automatically loaded by libGL.so.
+
<sect2>Troubleshooting
<p>
<itemize>
@@ -539,6 +638,9 @@
bit/pixel screen mode.
Use <tt/xdpyinfo/ to verify that all your visuals are depth 16.
Edit your XF86Config file if needed.
+ <item>
+ The <tt>/dev/3dfx</tt> device is not used for DRI; it's only for
+ Glide on older 3dfx hardware.
</itemize>
<sect2>Performance
@@ -565,6 +667,9 @@
<p>
<itemize>
<item>
+ Glide cannot be used directly; only OpenGL-based programs are
+ supported on the Voodoo3.
+ <item>
SSystem has problems because of poorly set near and far
clipping planes.
The office.unc Performer model also suffers from this problem.
@@ -573,10 +678,120 @@
<sect1>Intel i810
<p>
+ Information to be added in the future.
+
<sect1>Matrox G400
<p>
+ <sect2>Configuration
+<p>
+ Your XF86Config file's device section must specify the
+ <tt>mga</tt> device:
+ <verb>
+ Section "Device"
+ Identifier "G400"
+ VendorName "Matrox"
+ Driver "mga"
+ EndSection
+ </verb>
+ The Screen section should then reference the G400 mga device:
+ <verb>
+ Section "Screen"
+ Identifier "Screen 1"
+ Device "G400"
+ Monitor "High Res Monitor"
+ DefaultDepth 16
+ Subsection "Display"
+ Depth 16
+ Modes "1280x1024" "1024x768" "800x600" "640x480"
+ ViewPort 0 0
+ EndSubsection
+ EndSection
+ </verb>
+ <p>
+ The kernel module for the G400 is named <tt>mga.o</tt> and
+ should be installed in /lib/modules/KERNEL-VERSION/misc/.
+ It will be automatically loaded by the Xserver if needed.
+ <p>
+ The DRI 3D driver for the G400 should be in
+ <tt>/usr/X11R6/lib/modules/dri/mga_dri.so</tt>.
+ This will be automatically loaded by libGL.so.
+
+ <sect2>Troubleshooting
+<p>
+ <itemize>
+ <item>
+ 3D acceleration for the G400 is only supported in the 16
+ bit/pixel screen mode at this time. 32bpp will be supported
+ in the future.
+ Use <tt/xdpyinfo/ to verify that all your visuals are depth 16.
+ Edit your XF86Config file if needed.
+ </itemize>
+
+ <sect2>Performance
+<p>
+ No data at this time.
+
+ <sect2>Known Problems
+<p>
+ No data at this time.
+
+
<sect1>ATI Rage 128
<p>
+ <sect2>Configuration
+<p>
+ Your XF86Config file's device section must specify the
+ <tt>r128</tt> device:
+ <verb>
+ Section "Device"
+ Identifier "Rage128"
+ VendorName "ATI"
+ Driver "r128"
+ EndSection
+ </verb>
+ The Screen section should then reference the Rage 128 device:
+ <verb>
+ Section "Screen"
+ Identifier "Screen 1"
+ Device "Rage128"
+ Monitor "High Res Monitor"
+ DefaultDepth 16
+ Subsection "Display"
+ Depth 16
+ Modes "1280x1024" "1024x768" "800x600" "640x480"
+ ViewPort 0 0
+ EndSubsection
+ Subsection "Display"
+ Depth 32
+ Modes "1280x1024" "1024x768" "800x600" "640x480"
+ ViewPort 0 0
+ EndSubsection
+ EndSection
+ </verb>
+ <p>
+ The kernel module for the Rage 128 is named <tt>r128.o</tt> and
+ should be installed in /lib/modules/KERNEL-VERSION/misc/.
+ It will be automatically loaded by the Xserver if needed.
+ <p>
+ The DRI 3D driver for the Rage 128 should be in
+ <tt>/usr/X11R6/lib/modules/dri/r128_dri.so</tt>.
+ This will be automatically loaded by libGL.so.
+ <p>
+ You may also set your screen depth to 32 for 32bpp mode.
+ <p>
+
+ <sect2>Performance
+<p>
+ While PCI Rage 128 based cards are supported, they do not yet
+ support PCI GART, so they will not perform as well as their
+ AGP counterparts.
+
+ <sect2>Known Problems
+<p>
+ DGA is not yet supported in the ATI Rage 128 X server. This
+ feature will be added in a future release.
+
+
<sect1>3DLabs Oxygen GMX 2000
<p>
The driver for this hardware was experimental and is no longer being
@@ -621,6 +836,50 @@
which will be addressed in the future.
+ <sect1>libGL.so and dlopen()
+<p>
+ A number of popular OpenGL applications on Linux (such as Quake3,
+ HereticII, Heavy Gear 2, etc) dynamically open the libGL.so
+ library at runtime with dlopen(), rather than linking with -lGL
+ at compile/link time.
+<p>
+ If dynamic loading of libGL.so is not implemented carefully, there
+ can be a number of serious problems.
+ Here are the things to be careful of in your application:
+ <itemize>
+ <item>Specify the RTLD_GLOBAL flag to dlopen().
+ If you don't do this then you'll likely see a runtime error message
+ complaining that _glapi_Context is undefined when libGL.so
+ tries to open a hardware-specific driver.
+ Without this flag, <em>nested</em> opening of dynamic libraries
+ does not work.
+ <item>Do not close the library with dlclose() until after
+ XCloseDisplay() has been called.
+ When libGL.so initializes itself it registers several callbacks
+ functions with Xlib.
+ When XCloseDisplay() is called those callback functions are
+ called.
+ If libGL.so has already been unloaded with dlclose() this will
+ cause a segmentation fault.
+ <item>
+ Your application should link with -lpthread.
+ On Linux, libGL.so uses the pthreads library in order to provide
+ thread safety.
+ There is apparently a bug in the dlopen()/dlclose() code which
+ causes crashes if the library uses pthreads but the parent
+ application doesn't.
+ The only known work-around is to link the application with
+ -lpthread.
+ </itemize>
+
+ Some applications don't yet incorporate these procedures and
+ may fail.
+ For example, changing the graphics settings in some video games
+ will expose this problem.
+ The DRI developers are working with game vendors to prevent this
+ problem in the future.
+
+
<sect1>Bug Database
<p>
The DRI bug database which includes bugs related to specific
@@ -654,6 +913,9 @@
<item>Visit the <htmlurl url="http://dri.sourceforge.net"
name="DRI project on SourceForge.net"> for the latest development
news about the DRI and 3D drivers.
+ <item>The <htmlurl url="http://dri.sourceforge.net/DRIcompile.html"
+ name="DRI Compilation Guide"> explains how to download, compile
+ and install the DRI for yourself.
</itemize>
<sect1>Support
@@ -664,54 +926,13 @@
<htmlurl url="http://sourceforge.net/mail/?group_id=387"
name="SourceForge"> is a forum for people to discuss DRI problems.
<item>
- XXX IHV support?
- <item>
- XXX Linux distro support?
+ In the future there may be IHV and Linux vendor support resources
+ for the DRI.
</itemize>
</article>
-<!--
-1. Introduction
-2. Supported Hardware
-3. Prerequisite Software
-4. Start-Up
-5. Using 3D Acceleration
- 5.1 libGL.so
- 5.2 glxinfo
- 5.3 Environment variables
-6. General Trouble Shooting
-7. Hardware-Specific Information
- 7.1 3dfx
- 7.2 Intel i810
- 7.3 Matrox G400
- 7.4 ATI Rage 128
- 7.5 3DLabs Gamma
-8. Limitation and Known Bugs
- 8.1 OpenGL
- 8.2 GLX
- 8.3 Signal Handling
- 8.4 Scheduling
- 8.5 Bug Database
-9. Resources
- 9.1 Software Resources
- GLU
- GLUT
- Glide3
- Utilities and demos
- Sample XF86Config files
- 9.2 Documentation
- www.XFree86.org
- www.opengl.org
- www.linux.com
- www.precisioninsight.com
- sourceforge.net
- 9.3 Support
- IHVs
- RedHat
- -->
-
<!-- Local Variables: -->
<!-- fill-column: 72 -->
<!-- End: -->
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/DRIcomp.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/DRIcomp.sgml
new file mode 100644
index 000000000..5d0888342
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/DRIcomp.sgml
@@ -0,0 +1,501 @@
+<!doctype linuxdoc system>
+<!-- Created: Sun Mar 12 13:00:00 2000 by brian@precisioninsight.com -->
+<!-- Revised: Fri May 19 09:36:02 2000 by martin@valinux.com -->
+<!-- $Id: DRIcomp.sgml,v 1.6.14.1 2000/06/07 16:06:45 brianp Exp $ -->
+
+ <article>
+
+ <title>DRI Compilation Guide
+ <author>
+ <htmlurl url="http://www.precisioninsight.com/"
+ name="Precision Insight, Inc.">
+ <date>18 May 2000
+
+ <ident>
+ $XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/DRI.sgml,v 1.3 2000/04/05 05:38:41 brianp Exp $
+ </ident>
+
+ <toc>
+
+ <sect>Preamble
+
+ <sect1>Copyright
+ <p>
+ <bf>Copyright &copy; 2000 by Precision Insight, Inc.,
+ Cedar Park, Texas.
+ All Rights Reserved.</bf>
+ <p>
+ <bf>Permission is granted to make and distribute verbatim copies
+ of this document provided the copyright notice and this permission
+ notice are preserved on all copies.</bf>
+
+ <sect1>Trademarks
+ <p>
+ OpenGL is a registered trademark and SGI is a trademark of
+ Silicon Graphics, Inc.
+ Unix is a registered trademark of The Open Group.
+ The `X' device and X Window System are trademarks of The Open Group.
+ XFree86 is a trademark of The XFree86 Project.
+ Linux is a registered trademark of Linus Torvalds.
+ Intel is a registered trademark of Intel Corporation.
+ 3Dlabs, GLINT, and Oxygen are either registered trademarks or
+ trademarks of 3Dlabs Inc. Ltd.
+ 3dfx, Voodoo3, Voodoo4, and Voodoo5 are registered trademarks of
+ 3dfx Interactive, Incorporated.
+ Matrox is a registered trademark of Matrox Electronic Systems Ltd.
+ ATI Rage is a registered trademark of ATI Technologies, Inc.
+ All other trademarks mentioned are the property of their
+ respective owners.
+
+
+ <sect>Introduction
+ <p>
+ This document describes how to download, compile and install the
+ DRI project.
+ This information is intended for experienced Linux developers.
+ Beginners are probably better off installing precompiled packages.
+ <p>
+ Edits, corrections and updates to this document may be mailed
+ to brian@precisioninsight.com.
+
+
+ <sect>Prerequisites
+ <p>
+ You'll need the following:
+ <itemize>
+ <item>At least 400MB of free disk space. More is needed if you want
+ to build with debugging information or keep several build trees.
+ <item>A fast system. Using a PIII-550 it takes about 1/2 hour to
+ build everthing.
+ <item>GCC compiler and related tools.
+ <item>ssh (secure shell) for registed developer downloading of the
+ DRI source tree
+ </itemize>
+
+ <p>
+ For 3dfx Voodoo3 hardware, you'll also need:
+ <itemize>
+ <item>Glide3x headers and runtime library if you want to use the
+ 3dfx driver.
+ These can be obtained from
+ <htmlurl url="http://linux.3dfx.com/open_source/glide_kit.htm"
+ name="linux.3dfx.com">.
+ <item>Linux kernel 2.2.x.
+ The DRI developers have been using stock RedHat 6.1 systems
+ (kernel 2.2.12-20).
+ Later kernel versions will be supported in the future.
+ </itemize>
+
+ <p>
+ For Matrox G400 hardware, you'll also need:
+ <itemize>
+ <item>Linux kernel 2.3.51. Other kernel versions may work but
+ this one is known to work.
+ </itemize>
+
+ <p>
+ For ATI Rage hardware, you'll also need:
+ <itemize>
+ <item>Linux kernel 2.3.51. Other kernel versions may work but
+ this one is known to work.
+ </itemize>
+
+
+ <sect>Kernel preparation
+ <p>
+ You may have to upgrade your Linux kernel in order to use the DRI.
+ This is because you need a kernel version which supports AGP.
+ Building a new Linux kernel can be difficult for beginners but
+ there are resouces on the Internet to help.
+ This document assumes experience with configuring, building and
+ installing Linux kernels.
+ <p>
+ Linux kernels can be downloaded from
+ <htmlurl url="http://www.kernel.org/pub/linux/kernel/"
+ name="www.kernel.org">
+ <p>
+ Download the needed kernel and put it in /usr/src.
+ Create a directory for the source and unpack it.
+ For example:
+ <verb>
+ cd /usr/src
+ rm -f linux
+ mkdir linux-2.3.51
+ ln -s linux-2.3.51 linux
+ bzcat linux-2.3.51.tar.bz2 | tar xf -
+ </verb>
+ <p>
+ Now configure your kernel.
+ You might, for example, use <tt>make menuconfig</tt> and do the
+ following:
+
+ <itemize>
+ <item>Go to <em>Code maturity level options</em>
+ <item>Enable <em>Prompt for development and/or incomplete
+ code/drivers</em>
+ <item>hit ESC
+ <item>Go to <em>Character devices</em>
+ <item>Disable <em>Direct Rendering Manager (XFree86 DRI support)</em>
+ since we'll use the DRI module from the XFree86/DRI tree.
+ <item>Go to <em>/dev/agpgart (AGP Support) (EXPERIMENTAL) (NEW)</em>
+ <item>Hit SPACE twice
+ <item>Enable all chipsets' support for AGP
+ </itemize>
+
+ <p>It's recommended that you turn on MTRRs under <em>Processor type
+ and Features</em>, but not required.
+
+ <p>
+ Configure the rest of the kernel as required for your system
+ (i.e. ethernet, scsi, etc)
+ <p>
+ Exit, saving your kernel configuration.
+ <p>
+ Edit your /etc/lilo.conf file.
+ Make sure you have an image entry as follows (or similar):
+ <verb>
+ image=/boot/vmlinuz
+ label=linux.2.3.51
+ read-only
+ root=/dev/hda1
+ </verb>
+ <p>
+ The important part is that you have /boot/vmlinuz without a
+ trailing version number.
+ If this is the first entry in your /etc/lilo.conf AND you
+ haven't set a default, then this will be your default kernel.
+
+ <p>
+ Now compile the new kernel:
+
+ <verb>
+ cd /usr/src/linux-2.3.51
+ make dep ; make bzImage
+ make modules ; make modules_install
+ make install
+ </verb>
+ Note that the final part, make install, will automatically run
+ lilo for you.
+ <p>
+ Now reboot to use this new kernel.
+
+
+ <sect>Downloading the XFree86/DRI CVS Sources
+ <p>
+ The DRI project is hosted by VA Linux Systems'
+ <htmlurl url="http://sourceforge.net/project/?group_id=387"
+ name="SourceForge">.
+ The DRI source code, which is a subset of the XFree86 source tree,
+ is kept in a CVS repository there.
+ <p>
+ The DRI CVS sources may be accessed either anonymously or as a
+ registered SourceForge user.
+ It's recommended that you become a registered SourceForge user so
+ that you may submit non-annonymous bug reports and can participate
+ in the mailing lists.
+
+ <sect1>Anonymous CVS download:
+ <p>
+ <enum>
+ <item>Create a directory to store the CVS files:
+ <p>
+ <verb>
+ cd ~
+ mkdir DRI-CVS
+ </verb>
+ You could put your CVS directory in a different place but we'll
+ use <tt>~/DRI-CVS/</tt> here.
+ <p>
+ <item>Check out the CVS sources:
+ <p>
+ <verb>
+ cd ~/DRI-CVS
+ cvs -d:pserver:anonymous@cvs.dri.sourceforge.net:/cvsroot/dri login
+ (hit ENTER when prompted for a password)
+ cvs -z3 -d:pserver:anonymous@cvs.dri.sourceforge.net:/cvsroot/dri co xc
+ </verb>
+ <p>
+ The -z3 flag causes compression to be used in order to reduce
+ the download time.
+ </enum>
+
+
+ <sect1>Registered CVS download:
+ <p>
+ <enum>
+ <item>Create a directory to store the CVS files:
+ <p>
+ <verb>
+ cd ~
+ mkdir DRI-CVS
+ </verb>
+ You could put your CVS directory in a different place but we'll
+ use <tt>~/DRI-CVS/</tt> here.
+ <p>
+ <item>Set the CVS_RSH environment variable:
+ <p>
+ <verb>
+ setenv CVS_RSH ssh // if using csh or tcsh
+ export CVS_RSH=ssh // if using sh or bash
+ </verb>
+ <item>Check out the CVS sources:
+ <p>
+ <verb>
+ cd ~/DRI-CVS
+ cvs -z3 -dYOURID@cvs.dri.sourceforge.net:/cvsroot/dri co xc
+ </verb>
+ Replace <tt>YOURID</tt> with your CVS login name.
+ You'll be prompted to enter your sourceforge password.
+ <p>
+ The -z3 flag causes compression to be used in order to reduce
+ the download time.
+ </enum>
+
+
+ <sect>Updating your CVS sources
+ <p>
+ In the future you'll want to occasionally update your local copy of
+ the DRI source code to get the latest changes.
+ This can be done with:
+ <verb>
+ cd ~/DRI-CVS
+ cvs -z3 update -dA xc
+ </verb>
+ The -d flag causes any new subdirectories to be created and -A causes
+ most recent trunc sources to be fetched, not branch sources.
+
+
+ <sect>Compiling the XFree86/DRI tree
+ <sect1>Make a build tree
+ <p>
+ Rather than placing object files and library files right in the
+ source tree, they're instead put into a parallel <em>build</em> tree.
+ The build tree is made with the <tt>lndir</tt> command:
+ <verb>
+ cd ~/DRI-CVS
+ ln -s xc XFree40
+ mkdir build
+ cd build
+ lndir -silent -ignorelinks ../XFree40
+ </verb>
+ <p>
+ The build tree will be populated with symbolic links which point
+ back into the CVS source tree.
+ <p>
+ Advanced users may have several build trees for compiling and
+ testing with different options.
+
+ <sect1>Edit the host.def file
+ <p>
+ The <tt>~/DRI-CVS/build/xc/config/cf/host.def</tt> file is used
+ to configure the XFree86 build process.
+ You can change it to customize your build options or make adjustments
+ for your particular system configuration
+ <p>
+ The default <tt>host.def</tt> file will look something like this:
+ <verb>
+ #define DefaultCCOptions -Wall
+ #define DefaultGcc2i386Opt -O2
+ #define LibraryCDebugFlags -O2
+ #define BuildServersOnly YES
+ #define XF86CardDrivers vga tdfx mga r128
+ #define LinuxDistribution LinuxRedHat
+ #define DefaultCCOptions -ansi GccWarningOptions -pipe
+ #define BuildXF86DRI YES
+ #define HasGlide3 YES
+ /* Optionally turn these on for debugging */
+ /* #define GlxBuiltInTdfx YES */
+ /* #define GlxBuiltInMga YES */
+ /* #define GlxBuiltInR128 YES */
+ /* #define DoLoadableServer NO */
+ #define SharedLibFont NO
+ </verb>
+ The <tt>ProjectRoot</tt> variable specifies where the XFree86 files
+ will be installed.
+ You probably don't want to use <tt>/usr/X11R6/</tt> because that
+ would overwrite your default X files.
+ The following is recommended:
+ <verb>
+ #define ProjectRoot /usr/XF86-main
+ </verb>
+ <p>
+ Especially note the <em>XF86CardDrivers</em> line to be sure your
+ driver is listed.
+ <p>
+ If you have 3dfx hardware be sure that the Glide 3x headers are
+ installed in <tt>/usr/include/glide3/</tt> and that the Glide 3x
+ library is installed at <tt>/usr/lib/libglide3x.so</tt>.
+ <p>
+ If you do not have 3dfx hardware comment out the <tt>HasGlide3</tt>
+ line in <tt>host.def</tt>.
+ <p>
+
+ <sect1>Compile
+ <p>
+ To compile the complete DRI tree:
+ <verb>
+ cd ~/DRI-CVS/build/xc/
+ make World >& World.LOG
+ </verb>
+ Or if you want to watch the compilation progress:
+ <verb>
+ cd ~/DRI-CVS/build/xc/
+ make World >& World.LOG &
+ tail -f World.LOG
+ </verb>
+ With the default compilation flags it's normal to get a lot of
+ warnings during compilation.
+ <p>
+ Building will take some time so you may want to go check your
+ email or visit slashdot.
+
+ <sect1>Check for compilation errors
+ <p>
+ Using your text editor, examine <tt>World.LOG</tt> for errors
+ by searching for the pattern <tt>***</tt>.
+ <p>
+ Verify that the DRI kernel module(s) for your system were built:
+ <verb>
+ cd ~/DRI-CVS/build/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel
+ ls
+ </verb>
+ <p>
+ For the 3dfx Voodoo, you should see <em>tdfx.o</em>.
+ For the Matrox G400, you should see <em>mga.o</em>.
+ For the ATI Rage 128, you should see <em>r128.o</em>.
+ <p>
+ If the DRI kernel module(s) failed to build you should verify
+ that you're using the right version of the Linux kernel.
+ The most recent kernels are not always supported.
+ <p>
+ If your build machine is running a different version of the kernel
+ than your target machine (i.e. 2.2.12-20 vs. 2.3.99-pre6), make will
+ select the wrong kernel headers. This can be fixed by explicitly
+ setting the value of <tt>TREE</tt>.
+ If the path to your kernel source is
+ <tt>/bigdisk/linux-2.3.99-pre6</tt>,
+ <verb>
+ cd ~/DRI-CVS/build/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel
+ make TREE=/bigdisk/linux-2.3.99-pre6
+ </verb>
+ or alternatively, edit Makefile to include this change.
+ <p>
+ After fixing the errors, do <tt>make World</tt> again.
+ Later, you might just compile parts of the source tree but it's
+ important that the whole tree will build first.
+
+
+ <sect>Installing
+ <p>
+ After the DRI tree has been compiled you can install the XFree86
+ headers, libraries, programs, etc for testing.
+
+ <sect1>X Installation
+ <p>
+ As mentioned above, the install directory is specified by the
+ <tt>ProjectRoot</tt> variable in the <tt>host.def</tt> file.
+ Create that directory now if it doesn't already exist:
+ <verb>
+ mkdir /usr/XF86-main
+ </verb>
+ <p>
+ You'll have to change to root since the install process puts
+ several files in <tt>/etc/X11/</tt> and sets the setuid flag on
+ the X server executable.
+ <verb>
+ cd ~/DRI-CVS/build/xc
+ su
+ make install
+ </verb>
+ Edit your <tt>/etc/ld.so.conf</tt> file and put
+ <tt>/usr/XF86-main/lib</tt> as the first line.
+ Continue with:
+ <verb>
+ ldconfig
+ exit
+ </verb>
+ <p>
+ Look in <tt>/usr/XF86-main</tt> to be sure the files installed
+ there.
+ <P>
+ Strictly speaking, installing the DRI tree isn't required.
+ It's possible to run and test the X server directly from the
+ build directory but it's a bit error prone.
+
+ <sect1>Update Locale Information
+ <p>
+ To update your X locale information do the following:
+ <verb>
+ cd ~/DRI-CVS/build/xc/nls
+ xmkmf -a
+ make
+ make install
+ </verb>
+ This will prevent a locale error message from being printed
+ when you run Xlib programs.
+
+ <sect>X Server Configuration
+ <p>
+ If your X server is currently running you'll have to stop it
+ and return to a virtual terminal.
+ <p>
+ First, setup your XF86Config file.
+ It should load the GLX and DRI modules and specify the driver to
+ use for your hardware.
+ See the <htmlurl url="http://dri.sourceforge.net/DRIuserguide.html"
+ name="DRI User Guide"> for detailed information.
+ <p>
+ You may want to make a backup copy of your existing
+ <tt>/etc/X11/XF86Config</tt> file first.
+ <p>
+ It's very important that you set the <tt>ModulePath</tt> option to
+ point to your installation directory:
+ <verb>
+ ModulePath "/usr/XF86-main/lib/modules"
+ </verb>
+ <p>
+ Double check with this:
+ <verb>
+ grep ModulePath /etc/X11/XF86Config
+ </verb>
+ <p>
+ Next, your <tt>~/.xinitrc</tt> file controls which clients will be
+ launched when your X server starts.
+ You might put the following in yours:
+ <verb>
+ xset b off
+ xsetroot -solid "#004070"
+ xmodmap -e "clear mod4"
+ xrdb -merge ~/.Xdefaults
+ xterm -geometry +0+0 &
+ xterm -geometry +512+0 &
+ fvwm
+ </verb>
+ <p>
+
+ <sect>X Server Start-up
+ <p>
+ The X server can be started with:
+ <p>
+ <verb>
+ xinit -- /usr/XF86-main/bin/XFree86
+ </verb>
+ <p>
+ Automatic loading of DRM kernel modules was added to the X server
+ in XFree86 4.0.1.
+ This feature, and manual loading of kernel modules, is documented
+ in the DRI user guide.
+ <p>
+ At this point your X server should be up and running with
+ hardware-accelerated direct rendering.
+ Please read the
+ <htmlurl url="http://dri.sourceforge.net/DRIuserguide.html"
+ name="DRI User Guide"> for trouble shooting information.
+
+
+ </article>
+
+
+ <!-- Local Variables: -->
+ <!-- fill-column: 72 -->
+ <!-- End: -->
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile
index c8624e19f..d72589c49 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile
@@ -14,10 +14,12 @@ DRIINCLUDES=-I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri
SRCS = glint_driver.c pm2_dac.c pm2ramdac.c pm2_accel.c pm_dac.c IBMramdac.c \
pm_accel.c tx_dac.c tx_accel.c pm2v_dac.c pm2vramdac.c pm2_video.c \
- TIramdac.c dualmx_dac.c dualmx_accel.c glint_shadow.c $(DRISRC)
+ TIramdac.c dualmx_dac.c dualmx_accel.c glint_shadow.c $(DRISRC) \
+ glint_dga.c
OBJS = glint_driver.o pm2_dac.o pm2ramdac.o pm2_accel.o pm_dac.o IBMramdac.o \
pm_accel.o tx_dac.o tx_accel.o pm2v_dac.o pm2vramdac.o pm2_video.o \
- TIramdac.o dualmx_dac.o dualmx_accel.o glint_shadow.o $(DRIOBJ)
+ TIramdac.o dualmx_dac.o dualmx_accel.o glint_shadow.o $(DRIOBJ) \
+ glint_dga.o
#if defined(XF86DriverSDK)
INCLUDES = -I. -I../../include
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_accel.c
index a6d34a4bf..974ee3b4f 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_accel.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_accel.c
@@ -105,7 +105,6 @@ DualMXInitializeEngine(ScrnInfoPtr pScrn)
GLINTPtr pGlint = GLINTPTR(pScrn);
pGlint->rasterizerMode = RMMultiGLINT;
- pGlint->pprod |= FBRM_ScanlineInt2;
/* Initialize the Accelerator Engine to defaults */
@@ -120,8 +119,10 @@ DualMXInitializeEngine(ScrnInfoPtr pScrn)
/* Make sure the rest of the register writes go to both MX's */
GLINT_SLOW_WRITE_REG(3, BroadcastMask);
+ GLINT_SLOW_WRITE_REG(pGlint->rasterizerMode, RasterizerMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode);
- GLINT_SLOW_WRITE_REG(pGlint->pprod, LBReadMode);
+ GLINT_SLOW_WRITE_REG(pGlint->pprod | LBRM_ScanlineInt2, LBReadMode);
+ pGlint->pprod |= FBRM_ScanlineInt2;
GLINT_SLOW_WRITE_REG(pGlint->pprod, FBReadMode);
GLINT_SLOW_WRITE_REG(0, dXSub);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWriteMode);
@@ -149,7 +150,6 @@ DualMXInitializeEngine(ScrnInfoPtr pScrn)
GLINT_SLOW_WRITE_REG(0x400, FilterMode);
GLINT_SLOW_WRITE_REG(0xffffffff, FBHardwareWriteMask);
GLINT_SLOW_WRITE_REG(0xffffffff, FBSoftwareWriteMask);
- GLINT_SLOW_WRITE_REG(pGlint->rasterizerMode, RasterizerMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTDepth);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBSourceOffset);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBPixelOffset);
@@ -172,6 +172,7 @@ DualMXInitializeEngine(ScrnInfoPtr pScrn)
GLINT_SLOW_WRITE_REG(0x0, PixelSize);
break;
}
+
pGlint->ROP = 0xFF;
pGlint->ClippingOn = FALSE;
pGlint->startxsub = 0;
@@ -212,32 +213,34 @@ DualMXAccelInit(ScreenPtr pScreen)
infoPtr->SetClippingRectangle = DualMXSetClippingRectangle;
infoPtr->DisableClipping = DualMXDisableClipping;
infoPtr->ClippingFlags = HARDWARE_CLIP_MONO_8x8_FILL |
+#if 0
HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
+#endif
HARDWARE_CLIP_SOLID_FILL;
infoPtr->SolidFillFlags = 0;
infoPtr->SetupForSolidFill = DualMXSetupForFillRectSolid;
infoPtr->SubsequentSolidFillRect = DualMXSubsequentFillRectSolid;
- /*
- * The following optimized routines are copied from tx_accel.c,
- * but haven't been ported to a dual MX board.
- */
-#ifdef NOT_DONE
infoPtr->SolidLineFlags = 0;
infoPtr->PolySegmentThinSolidFlags = 0;
infoPtr->PolylinesThinSolidFlags = 0;
infoPtr->SetupForSolidLine = DualMXSetupForSolidLine;
infoPtr->SubsequentSolidHorVertLine = DualMXSubsequentHorVertLine;
- infoPtr->SubsequentSolidBresenhamLine =
+ if (!(pScrn->overlayFlags & OVERLAY_8_32_PLANAR))
+ {
+ infoPtr->SubsequentSolidBresenhamLine =
DualMXSubsequentSolidBresenhamLine;
+ }
infoPtr->PolySegmentThinSolid = DualMXPolySegmentThinSolidWrapper;
infoPtr->PolylinesThinSolid = DualMXPolylinesThinSolidWrapper;
+#if 0
infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY |
ONLY_LEFT_TO_RIGHT_BITBLT;
infoPtr->SetupForScreenToScreenCopy = DualMXSetupForScreenToScreenCopy;
infoPtr->SubsequentScreenToScreenCopy = DualMXSubsequentScreenToScreenCopy;
+#endif
infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
HARDWARE_PATTERN_SCREEN_ORIGIN |
@@ -246,6 +249,7 @@ DualMXAccelInit(ScreenPtr pScreen)
infoPtr->SubsequentMono8x8PatternFillRect =
DualMXSubsequentMono8x8PatternFillRect;
+#if 0
if (!pGlint->UsePCIRetry) {
infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
TRANSPARENCY_ONLY |
@@ -285,6 +289,7 @@ DualMXAccelInit(ScreenPtr pScreen)
infoPtr->SubsequentCPUToScreenColorExpandFill =
DualMXSubsequentCPUToScreenColorExpandFill;
}
+#endif
infoPtr->ColorExpandRange = MAX_FIFO_ENTRIES;
@@ -299,7 +304,6 @@ DualMXAccelInit(ScreenPtr pScreen)
pScrn->bitsPerPixel / 8);
xf86InitFBManager(pScreen, &AvailFBArea);
-#endif /* NOT_DONE */
return (XAAInit(pScreen, infoPtr));
}
@@ -312,11 +316,6 @@ static void DualMXLoadCoord(
){
GLINTPtr pGlint = GLINTPTR(pScrn);
- /*
- * Optimization from tx_accel.c where these values are cached on the
- * host doesn't appear to work. We definitely need to reload at least
- * the StartXDom value. I'll play it safe and reload them all.
- */
GLINT_WRITE_REG(w<<16, StartXSub);
GLINT_WRITE_REG(x<<16,StartXDom);
GLINT_WRITE_REG(y<<16,StartY);
@@ -686,14 +685,15 @@ DualMXSubsequentMono8x8PatternFillRect(
if (pGlint->FrameBufferReadMode != -1) {
if (pGlint->ROP == GXcopy) {
GLINT_WRITE_REG(pGlint->BackGroundColor, FBBlockColor);
- GLINT_WRITE_REG(PrimitiveTrapezoid | FastFillEnable,Render);
+ span = 0;
} else {
GLINT_WRITE_REG(pGlint->BackGroundColor, PatternRamData0);
- GLINT_WRITE_REG(2<<1|2<<4|patternx<<7|patterny<<12|ASM_InvertPattern |
+ span = SpanOperation;
+ }
+ GLINT_WRITE_REG(2<<1|2<<4|patternx<<7|patterny<<12|ASM_InvertPattern |
UNIT_ENABLE, AreaStippleMode);
- GLINT_WRITE_REG(AreaStippleEnable | SpanOperation | FastFillEnable |
+ GLINT_WRITE_REG(AreaStippleEnable | span | FastFillEnable |
PrimitiveTrapezoid, Render);
- }
}
if (pGlint->ROP == GXcopy) {
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_dac.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_dac.c
index a17ab1c8b..0a7728ded 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_dac.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_dac.c
@@ -454,8 +454,7 @@ DualMXInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
pReg->glintRegs[VTGVSyncStart >> 3] = temp2;
pReg->glintRegs[VTGVBlankEnd >> 3] = mode->CrtcVTotal - mode->CrtcVDisplay;
- pReg->glintRegs[VTGPolarity >> 3] = (((mode->Flags & V_PHSYNC) ? 0:2)<<2) |
- ((mode->Flags & V_PVSYNC) ? 0 : 2) | (0xb0);
+ pReg->glintRegs[VTGPolarity >> 3] = 0xba;
pReg->glintRegs[VClkCtl >> 3] = 0;
pReg->glintRegs[VTGVGateStart >> 3] = pReg->glintRegs[VTGVBlankEnd>>3] - 1;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h
index a84f7219a..9ef168854 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h
@@ -105,6 +105,10 @@ typedef struct {
unsigned char * IOBaseVGA;
unsigned char * FbBase;
long FbMapSize;
+ DGAModePtr DGAModes;
+ int numDGAModes;
+ Bool DGAactive;
+ int DGAViewportStatus;
Bool DoubleBuffer;
Bool NoAccel;
Bool FBDev;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dga.c
new file mode 100644
index 000000000..f3aa7ebe5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dga.c
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2000 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ */
+/* $XFree86: $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "glint.h"
+#include "glint_regs.h"
+#include "dgaproc.h"
+
+static Bool GLINT_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
+ int *, int *, int *);
+static Bool GLINT_SetMode(ScrnInfoPtr, DGAModePtr);
+static void GLINT_Sync(ScrnInfoPtr);
+static int GLINT_GetViewport(ScrnInfoPtr);
+static void GLINT_SetViewport(ScrnInfoPtr, int, int, int);
+static void GLINT_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+static void GLINT_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+static void GLINT_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
+ unsigned long);
+
+static
+DGAFunctionRec GLINTDGAFuncs = {
+ GLINT_OpenFramebuffer,
+ NULL,
+ GLINT_SetMode,
+ GLINT_SetViewport,
+ GLINT_GetViewport,
+ GLINT_Sync,
+ GLINT_FillRect,
+ NULL,
+#if 0
+ GLINT_BlitRect,
+ GLINT_BlitTransRect
+#else
+ NULL
+#endif
+};
+
+Bool
+GLINTDGAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ DGAModePtr modes = NULL, newmodes = NULL, currentMode;
+ DisplayModePtr pMode, firstMode;
+ int Bpp = pScrn->bitsPerPixel >> 3;
+ int num = 0;
+ Bool oneMore;
+
+ pMode = firstMode = pScrn->modes;
+
+ while(pMode) {
+
+ if(0 /*pScrn->displayWidth != pMode->HDisplay*/) {
+ newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec));
+ oneMore = TRUE;
+ } else {
+ newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec));
+ oneMore = FALSE;
+ }
+
+ if(!newmodes) {
+ xfree(modes);
+ return FALSE;
+ }
+ modes = newmodes;
+
+SECOND_PASS:
+
+ currentMode = modes + num;
+ num++;
+
+ currentMode->mode = pMode;
+ currentMode->flags = DGA_CONCURRENT_ACCESS /*| DGA_PIXMAP_AVAILABLE*/;
+ if(!pGlint->NoAccel)
+ currentMode->flags |= DGA_FILL_RECT /*| DGA_BLIT_RECT*/;
+ if(pMode->Flags & V_DBLSCAN)
+ currentMode->flags |= DGA_DOUBLESCAN;
+ if(pMode->Flags & V_INTERLACE)
+ currentMode->flags |= DGA_INTERLACED;
+ currentMode->byteOrder = pScrn->imageByteOrder;
+ currentMode->depth = pScrn->depth;
+ currentMode->bitsPerPixel = pScrn->bitsPerPixel;
+ currentMode->red_mask = pScrn->mask.red;
+ currentMode->green_mask = pScrn->mask.green;
+ currentMode->blue_mask = pScrn->mask.blue;
+ currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor;
+ currentMode->viewportWidth = pMode->HDisplay;
+ currentMode->viewportHeight = pMode->VDisplay;
+ currentMode->xViewportStep = 1;
+ currentMode->yViewportStep = 1;
+ currentMode->viewportFlags = DGA_FLIP_RETRACE;
+ currentMode->offset = 0;
+ currentMode->address = pGlint->FbBase;
+
+ if(oneMore) { /* first one is narrow width */
+ currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L;
+ currentMode->imageWidth = pMode->HDisplay;
+ currentMode->imageHeight = pMode->VDisplay;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+ oneMore = FALSE;
+ goto SECOND_PASS;
+ } else {
+ currentMode->bytesPerScanline =
+ ((pScrn->displayWidth * Bpp) + 3) & ~3L;
+ currentMode->imageWidth = pScrn->displayWidth;
+ currentMode->imageHeight = pMode->VDisplay;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+ }
+
+ pMode = pMode->next;
+ if(pMode == firstMode)
+ break;
+ }
+
+ pGlint->numDGAModes = num;
+ pGlint->DGAModes = modes;
+
+ return DGAInit(pScreen, &GLINTDGAFuncs, modes, num);
+}
+
+
+static Bool
+GLINT_SetMode(
+ ScrnInfoPtr pScrn,
+ DGAModePtr pMode
+){
+ static int OldDisplayWidth[MAXSCREENS];
+ int index = pScrn->pScreen->myNum;
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ if(!pMode) { /* restore the original mode */
+ /* put the ScreenParameters back */
+
+ pScrn->displayWidth = OldDisplayWidth[index];
+
+ GLINTSwitchMode(index, pScrn->currentMode, 0);
+ pGlint->DGAactive = FALSE;
+ } else {
+ if(!pGlint->DGAactive) { /* save the old parameters */
+ OldDisplayWidth[index] = pScrn->displayWidth;
+
+ pGlint->DGAactive = TRUE;
+ }
+
+ pScrn->displayWidth = pMode->bytesPerScanline /
+ (pMode->bitsPerPixel >> 3);
+
+ GLINTSwitchMode(index, pMode->mode, 0);
+ }
+
+ return TRUE;
+}
+
+static int
+GLINT_GetViewport(
+ ScrnInfoPtr pScrn
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ return pGlint->DGAViewportStatus;
+}
+
+static void
+GLINT_SetViewport(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int flags
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINTAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
+ pGlint->DGAViewportStatus = 0; /* GLINTAdjustFrame loops until finished */
+}
+
+static void
+GLINT_FillRect (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned long color
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ if(pGlint->AccelInfoRec) {
+ (*pGlint->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
+ (*pGlint->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ SET_SYNC_FLAG(pGlint->AccelInfoRec);
+ }
+}
+
+static void
+GLINT_Sync(
+ ScrnInfoPtr pScrn
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ if(pGlint->AccelInfoRec) {
+ (*pGlint->AccelInfoRec->Sync)(pScrn);
+ }
+}
+
+static void
+GLINT_BlitRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ if(pGlint->AccelInfoRec) {
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ (*pGlint->AccelInfoRec->SetupForScreenToScreenCopy)(
+ pScrn, xdir, ydir, GXcopy, ~0, -1);
+ (*pGlint->AccelInfoRec->SubsequentScreenToScreenCopy)(
+ pScrn, srcx, srcy, dstx, dsty, w, h);
+ SET_SYNC_FLAG(pGlint->AccelInfoRec);
+ }
+}
+
+
+static void
+GLINT_BlitTransRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty,
+ unsigned long color
+){
+ /* this one should be separate since the XAA function would
+ prohibit usage of ~0 as the key */
+}
+
+
+static Bool
+GLINT_OpenFramebuffer(
+ ScrnInfoPtr pScrn,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *flags
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ *name = NULL; /* no special device */
+ *mem = (unsigned char*)pGlint->FbAddress;
+ *size = pGlint->FbMapSize;
+ *offset = 0;
+ *flags = DGA_NEED_ROOT;
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c
index 0913cada0..9aa55de42 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c
@@ -40,11 +40,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xf86PciInfo.h"
#include "xf86Pci.h"
-#define PSZ 8
-#include "cfb.h"
-#undef PSZ
-#include "cfb16.h"
-#include "cfb32.h"
+#include "fb.h"
#include "miline.h"
@@ -61,18 +57,7 @@ static void GLINTDestroyContext(ScreenPtr pScreen, drmContext hwContext,
DRIContextType contextStore);
static int
-GLINTDRIControlInitSingleMX(int drmSubFD, int irq)
-{
-
- int retcode;
-
- /* Perhaps add flag to for single mx here? */
- if ((retcode = drmCtlInstHandler(drmSubFD, irq))) return 1;
- return 0;
-}
-
-static int
-GLINTDRIControlInitDualMX(int drmSubFD, int irq)
+GLINTDRIControlInit(int drmSubFD, int irq)
{
int retcode;
@@ -105,7 +90,7 @@ GLINTInitVisualConfigs(ScreenPtr pScreen)
case 32:
/* if(pGlint->Overlay): differentiate overlays when we support
either alpha buffer or 3D rendering in Overlay */
- numConfigs = 5;
+ numConfigs = 4;
if (!(pConfigs = (__GLXvisualConfig *)xnfcalloc(
sizeof(__GLXvisualConfig),
@@ -260,6 +245,7 @@ GLINTInitVisualConfigs(ScreenPtr pScreen)
pConfigs[3].transparentIndex = 0;
pGlintConfigs[3].index = 3;
+#if 0
/* config 4: db=TRUE, depth=16, stencil=8, conformant (a lie) */
pConfigs[4].vid = -1;
pConfigs[4].class = -1;
@@ -291,6 +277,7 @@ GLINTInitVisualConfigs(ScreenPtr pScreen)
pConfigs[4].transparentAlpha = 0;
pConfigs[4].transparentIndex = 0;
pGlintConfigs[4].index = 4;
+#endif
break;
}
@@ -424,6 +411,7 @@ GLINTDRIScreenInit(ScreenPtr pScreen)
DRIDestroyInfoRec(pGlint->pDRIInfo);
return FALSE;
}
+
pDRIInfo->devPrivate = pGlintDRI;
pDRIInfo->devPrivateSize = sizeof(GLINTDRIRec);
pDRIInfo->contextSize = sizeof(GLINTDRIContextRec);
@@ -463,6 +451,11 @@ GLINTDRIScreenInit(ScreenPtr pScreen)
}
}
+ /* Tell the client driver how many MX's we have */
+ pGlintDRI->numMXDevices = pGlint->numMXDevices;
+ /* Tell the client about our screen size setup */
+ pGlintDRI->pprod = pGlint->pprod;
+
/* setup device specific direct rendering memory maps */
/* pci region 0: control regs, first 4k page, priveledged writes */
@@ -543,8 +536,8 @@ GLINTDRIScreenInit(ScreenPtr pScreen)
if ((bufs = drmAddBufs(pGlint->drmSubFD,
xf86ConfigDRI.bufs[i].count,
xf86ConfigDRI.bufs[i].size,
- 0, /* flags */
- 0 /* offset */)) <= 0) {
+ 0,
+ 0 /* flags */)) <= 0) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[drm] failure adding %d %d byte DMA buffers\n",
xf86ConfigDRI.bufs[i].count,
@@ -564,8 +557,8 @@ GLINTDRIScreenInit(ScreenPtr pScreen)
if ((bufs = drmAddBufs(pGlint->drmSubFD,
GLINT_DRI_BUF_COUNT,
GLINT_DRI_BUF_SIZE,
- 0, /* flags */
- 0 /* offset */)) <= 0) {
+ 0,
+ 0 /* flags */)) <= 0) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"[drm] failure adding %d %d byte DMA buffers\n",
GLINT_DRI_BUF_COUNT,
@@ -602,26 +595,13 @@ GLINTDRIScreenInit(ScreenPtr pScreen)
->thisCard)->funcnum);
}
- if (pGlint->numMXDevices == 2) {
- if ( (pGlint->irq <= 0) ||
- GLINTDRIControlInitDualMX(pGlint->drmSubFD, pGlint->irq) ) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[drm] cannot initialize dma with IRQ %d\n",
- pGlint->irq);
- DRICloseScreen(pScreen);
- return FALSE;
- }
- }
-
- if (pGlint->numMXDevices == 1) {
- if ( (pGlint->irq <= 0) ||
- GLINTDRIControlInitSingleMX(pGlint->drmSubFD, pGlint->irq) ) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[drm] cannot initialize dma with IRQ %d\n",
- pGlint->irq);
- DRICloseScreen(pScreen);
- return FALSE;
- }
+ if ( (pGlint->irq <= 0) ||
+ GLINTDRIControlInit(pGlint->drmSubFD, pGlint->irq) ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] cannot initialize dma with IRQ %d\n",
+ pGlint->irq);
+ DRICloseScreen(pScreen);
+ return FALSE;
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -670,7 +650,7 @@ GLINTCreateContext(ScreenPtr pScreen,
VisualPtr visual,
drmContext hwContext,
void *pVisualConfigPriv,
- DRIContextType context)
+ DRIContextType contextStore)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
GLINTPtr pGlint = GLINTPTR(pScrn);
@@ -1161,7 +1141,7 @@ GLINTDRISwapContext(
/* send gamma the context dump command */
GLINT_WAIT(3);
- if (pGlint->numMXDevices > 1)
+ if (pGlint->numMXDevices == 2)
GLINT_WRITE_REG(1, BroadcastMask);
GLINT_WRITE_REG(3<<14, FilterMode); /* context bits on gamma */
GLINT_WRITE_REG(GLINT_GAMMA_CONTEXT_MASK, ContextDump);
@@ -1206,7 +1186,7 @@ dumpIndex,readValue);
/* send context restore command */
GLINT_WAIT(1);
- if (pGlint->numMXDevices > 1)
+ if (pGlint->numMXDevices == 2)
GLINT_WRITE_REG(1, BroadcastMask);
GLINT_WAIT(3);
@@ -1235,7 +1215,7 @@ dumpIndex,pWC->Gamma[dumpIndex]);
pGlint->AccelInfoRec->NeedToSync = TRUE;
/* finally the MX portions */
- if (pGlint->numMXDevices > 1)
+ if (pGlint->numMXDevices == 2)
GLINT_SLOW_WRITE_REG(1, BroadcastMask);
GLINT_SLOW_WRITE_REG(pWC->MX1.CSStart, SStart);
GLINT_SLOW_WRITE_REG(pWC->MX1.CdSdx, dSdx);
@@ -1488,7 +1468,7 @@ dumpIndex,pWC->Gamma[dumpIndex]);
/* restore the 2D portion of the new context */
/* Restore MX1's registers */
- if (pGlint->numMXDevices > 1)
+ if (pGlint->numMXDevices == 2)
GLINT_SLOW_WRITE_REG(1, BroadcastMask);
GLINT_SLOW_WRITE_REG(pWC->MX1.CStartXDom, StartXDom);
GLINT_SLOW_WRITE_REG(pWC->MX1.CdXDom, dXDom);
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h
index 03f4d9fed..9e11edda8 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h
@@ -50,6 +50,8 @@ typedef struct {
drmMapFlags flagsControlRegs1;
drmMapFlags flagsControlRegs2;
drmMapFlags flagsControlRegs3;
+ int numMXDevices;
+ int pprod;
} GLINTDRIRec, *GLINTDRIPtr;
#define GLINT_DRI_BUF_COUNT 20
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h
index c92d90f98..e026f8b18 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h
@@ -42,15 +42,15 @@ extern void GlxSetVisualConfigs(
extern Bool GLINTCreateContext(ScreenPtr pScreen,
VisualPtr visual,
drmContext hwContext,
- void *pVisualConfigPriv,
- DRIContextType context);
+ void* pVisualConfigPriv,
+ DRIContextType contextStore);
extern void GLINTDRISwapContext( ScreenPtr pScreen,
DRISyncType syncType,
DRIContextType readContextType,
- void *readContextStore,
+ void* readContextStore,
DRIContextType writeContextType,
- void *writeContextStore);
+ void* writeContextStore);
/* Macros to Setup Generic Kernel Device Driver to Handle DMA for gamma */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c
index edd418ae3..f0b316729 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c
@@ -2658,6 +2658,9 @@ GLINTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
xf86SetBlackWhitePixels(pScreen);
+ if (!pGlint->ShadowFB)
+ GLINTDGAInit(pScreen);
+
if (pScrn->bitsPerPixel > 8) {
/* Fixup RGB ordering */
visual = pScreen->visuals + pScreen->numVisuals;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h
index f33e42c80..489bf8eed 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h
@@ -35,6 +35,9 @@
#define PCI_CHIP_3DLABS_PERMEDIA 0x04
#define PCI_CHIP_3DLABS_MX 0x06
#define PCI_CHIP_3DLABS_PERMEDIA2 0x07
+#define PCI_CHIP_3DLABS_GAMMA 0x08
+#define PCI_CHIP_3DLABS_PERMEDIA2V 0x09
+#define PCI_CHIP_3DLABS_PERMEDIA3 0x0A
#define PCI_CHIP_TI_PERMEDIA 0x3d04
#define CFGRevisionId 0x08
@@ -90,6 +93,10 @@
#define SCLK_SEL_MCLK_HALF (3 << 10)
#define ByDMAControl 0x00D8
+/* GLINT R3 & Permedia3 Region 0 Bypass Controls */
+#define PM3ByAperture1Mode 0x0300
+#define PM3ByAperture2Mode 0x0328
+
/* GLINT 500TX LocalBuffer Registers */
#define LBMemoryCtl 0x1000
#define LBNumBanksMask 0x00000001
@@ -192,6 +199,17 @@
#define PMFramebufferWriteMask 0x1140
#define PMCount 0x1180
+/* Permedia 3 & GLINT R3 Memory Control */
+#define PM3MemCounter 0x1000
+#define PM3MemBypassWriteMask 0x1008
+#define PM3MemScratch 0x1010
+#define PM3LocalMemCaps 0x1018
+#define PM3LocalMemTimings 0x1020
+#define PM3LocalMemControl 0x1028
+#define PM3LocalMemRefresh 0x1030
+#define PM3LocalMemPowerDown 0x1038
+#define PM3RemoteMemControl 0x1100
+
/* Framebuffer Registers */
#define FBMemoryCtl 0x1800
#define FBModeSel 0x1808
@@ -1146,14 +1164,15 @@
#define GLINT_READ_REG(r) \
GLINT_VERB_READ_REG(pGlint,r,__FILE__,__LINE__)
#else
-#define GLINT_WRITE_REG(v,r) \
-do{ \
- *(volatile CARD32 *)((char *)pGlint->IOBase+(r))=v; \
- mem_barrier(); \
-}while(0)
-#define GLINT_READ_REG(r) \
- (*(volatile CARD32 *)((char *)pGlint->IOBase+(r)))
-#endif
+
+#define GLINT_WRITE_REG(v,r) MMIO_OUT32(pGlint->IOBase,(unsigned long)r, v)
+#define GLINT_READ_REG(r) MMIO_IN32(pGlint->IOBase,(unsigned long)r)
+#define GLINT_SECONDARY_WRITE_REG(v,r) \
+ MMIO_OUT32(pGlint->IOBase,(unsigned long)r+0x10000, v)
+#define GLINT_SECONDARY_READ_REG(r) \
+ MMIO_IN32(pGlint->IOBase,(unsigned long)r+0x10000)
+
+#endif /* DEBUG */
#define GLINT_WAIT(n) \
do{ \
@@ -1179,23 +1198,12 @@ do{ \
GLINTDACDelay(5); \
}while(0)
-#define GLINT_SECONDARY_WRITE_REG(v,r) \
-do{ \
- *(volatile CARD32 *)((char *)pGlint->SecondaryBase+(r))=v; \
-}while(0)
-
-#define GLINT_SECONDARY_READ_REG(r) \
- (*(volatile CARD32 *)((char *)pGlint->SecondaryBase+(r)))
-
#define GLINT_SECONDARY_SLOW_WRITE_REG(v,r) \
do{ \
while(GLINT_READ_REG(InFIFOSpace)<1); \
GLINT_SECONDARY_WRITE_REG(v,r); \
}while(0)
-#define GLINT_LOAD_PAR(v,r) \
- *(unsigned long *)((char*)pGlint->IOBase+r) = *((unsigned long *) &v)
-
#define REPLICATE(r) \
{ \
if (pScrn->bitsPerPixel == 16) { \
@@ -1208,14 +1216,21 @@ do{ \
} \
}
+#ifndef XF86DRI
#define LOADROP(rop) \
{ \
- if (pGlint->ROP != rop) { \
+ if (pGlint->ROP != rop) { \
GLINT_WRITE_REG(rop<<1|UNIT_ENABLE, LogicalOpMode); \
pGlint->ROP = rop; \
} \
}
-
+#else
+#define LOADROP(rop) \
+ { \
+ GLINT_WRITE_REG(rop<<1|UNIT_ENABLE, LogicalOpMode); \
+ pGlint->ROP = rop; \
+ }
+#endif
#define CHECKCLIPPING \
{ \
@@ -1226,6 +1241,7 @@ do{ \
} \
}
+#ifndef XF86DRI
#define DO_PLANEMASK(planemask) \
{ \
if (planemask != pGlint->planemask) { \
@@ -1234,4 +1250,12 @@ do{ \
GLINT_WRITE_REG(planemask, FBHardwareWriteMask);\
} \
}
+#else
+#define DO_PLANEMASK(planemask) \
+ { \
+ pGlint->planemask = planemask; \
+ REPLICATE(planemask); \
+ GLINT_WRITE_REG(planemask, FBHardwareWriteMask);\
+ }
+#endif
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile
index 331396f38..9e167d6c7 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile
@@ -6,13 +6,9 @@ XCOMM
#define IHaveModules
#include <Server.tmpl>
-#
-# Uncomment these to build with DRI support when available
-#
-#undef BuildXF86DRI
#if BuildXF86DRI
-DRISRCS = i810_dri.c i810_drm.c
-DRIOBJS = i810_dri.o i810_drm.o
+DRISRCS = i810_dri.c
+DRIOBJS = i810_dri.o
DRIINCLUDES = -I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri \
-I$(XF86OSSRC)/linux/drm/kernel
DRIDEFINES = $(GLX_DEFINES)
@@ -63,7 +59,6 @@ InstallDriverSDKNonExecFile(i810_cursor.c,$(DRIVERSDKDIR)/drivers/i810)
InstallDriverSDKNonExecFile(i810_driver.c,$(DRIVERSDKDIR)/drivers/i810)
InstallDriverSDKNonExecFile(i810_dri.c,$(DRIVERSDKDIR)/drivers/i810)
InstallDriverSDKNonExecFile(i810_dri.h,$(DRIVERSDKDIR)/drivers/i810)
-InstallDriverSDKNonExecFile(i810_dripriv.h,$(DRIVERSDKDIR)/drivers/i810)
InstallDriverSDKNonExecFile(i810_io.c,$(DRIVERSDKDIR)/drivers/i810)
InstallDriverSDKNonExecFile(i810_memory.c,$(DRIVERSDKDIR)/drivers/i810)
InstallDriverSDKNonExecFile(i810_wmark.c,$(DRIVERSDKDIR)/drivers/i810)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h
index a37ddca72..030b66a91 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h
@@ -43,9 +43,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xaa.h"
#include "xf86Cursor.h"
-#undef XF86DRI
-
-
#ifdef XF86DRI
#include "xf86drm.h"
#include "sarea.h"
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c
index 0f67180d2..1a410bcd1 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c
@@ -271,6 +271,7 @@ I810WaitLpRing( ScrnInfoPtr pScrn, int n, int timeout_millis )
DRICloseScreen(screenInfo.screens[pScrn->scrnIndex]);
}
#endif
+ pI810->AccelInfoRec = NULL; /* Stops recursive behavior */
FatalError("lockup\n");
}
@@ -301,13 +302,9 @@ I810Sync( ScrnInfoPtr pScrn )
#ifdef XF86DRI
/* VT switching tries to do this.
*/
- if (!pI810->LockHeld) {
+ if (!pI810->LockHeld && pI810->directRenderingEnabled) {
return;
}
-
-
-/* if (pI810->directRenderingEnabled) */
-/* DRIUnlockLockQueiscent( pScrn->pScreen ); */
#endif
/* Send a flush instruction and then wait till the ring is empty.
@@ -635,19 +632,19 @@ I810RefreshRing(ScrnInfoPtr pScrn)
}
-
+/* Emit on gaining VT?
+ */
void
I810EmitInvarientState(ScrnInfoPtr pScrn)
{
I810Ptr pI810 = I810PTR(pScrn);
- BEGIN_LP_RING( 8 );
+ BEGIN_LP_RING( 10 );
OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
OUT_RING( GFX_CMD_CONTEXT_SEL | CS_UPDATE_USE | CS_USE_CTX0 );
OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
OUT_RING( 0 );
-
OUT_RING( GFX_OP_COLOR_CHROMA_KEY );
OUT_RING( CC1_UPDATE_KILL_WRITE |
CC1_DISABLE_KILL_WRITE |
@@ -658,5 +655,8 @@ I810EmitInvarientState(ScrnInfoPtr pScrn)
OUT_RING( 0 );
OUT_RING( 0 );
+/* OUT_RING( CMD_OP_Z_BUFFER_INFO ); */
+/* OUT_RING( pI810->DepthBuffer.Start | pI810->auxPitchBits); */
+
ADVANCE_LP_RING();
}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c
index 7de2d1d7a..e2c48f68f 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c
@@ -73,13 +73,26 @@ Bool I810InitDma(ScrnInfoPtr pScrn)
{
I810Ptr pI810 = I810PTR(pScrn);
I810RingBuffer *ring = &(pI810->LpRing);
+ drmI810Init info;
Bool ret_val;
- ret_val = drmI810InitDma(pI810->drmSubFD, ring->mem.Start,
- ring->mem.End, ring->mem.Size,
- 6, 5, sizeof(XF86DRISAREARec));
- if(ret_val == FALSE)
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I810 Dma Initialization Failed\n");
+ info.start = ring->mem.Start;
+ info.end = ring->mem.End;
+ info.size = ring->mem.Size;
+ info.ring_map_idx = 6;
+ info.buffer_map_idx = 5;
+ info.sarea_off = sizeof(XF86DRISAREARec);
+
+ info.front_offset = 0;
+ info.back_offset = pI810->BackBuffer.Start;
+ info.depth_offset = pI810->DepthBuffer.Start;
+ info.w = pScrn->virtualX;
+ info.h = pScrn->virtualY;
+ info.pitch = pI810->auxPitch;
+ info.pitch_bits = pI810->auxPitchBits;
+
+ ret_val = drmI810InitDma(pI810->drmSubFD, &info);
+ if(ret_val == FALSE) ErrorF("I810 Dma Initialization Failed\n");
return ret_val;
}
@@ -214,7 +227,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
#if XFree86LOADER
/* Check that the GLX, DRI, and DRM modules have been loaded by testing
- * for canonical symbols in each module. */
+ * for known symbols in each module. */
if (!LoaderSymbol("GlxSetVisualConfigs")) return FALSE;
if (!LoaderSymbol("DRIScreenInit")) return FALSE;
if (!LoaderSymbol("drmAvailable")) return FALSE;
@@ -248,6 +261,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
pDRIInfo->drmDriverName = I810KernelDriverName;
pDRIInfo->clientDriverName = I810ClientDriverName;
pDRIInfo->busIdString = xalloc(64);
+
sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
((pciConfigPtr)pI810->PciInfo->thisCard)->busnum,
((pciConfigPtr)pI810->PciInfo->thisCard)->devnum,
@@ -370,7 +384,6 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
drmAgpAlloc(pI810->drmSubFD, 4096 * 1024, 1, NULL, &dcacheHandle);
pI810->dcacheHandle = dcacheHandle;
-
xf86DrvMsg(pScreen->myNum, X_INFO, "dcacheHandle : %p\n", dcacheHandle);
#define Elements(x) sizeof(x)/sizeof(*x)
@@ -386,10 +399,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
}
else {
back_size = i810_pitches[pitch_idx] * (pScrn->virtualY + 4);
- xf86DrvMsg(pScreen->myNum, X_INFO, "back_size: %d\n", back_size);
- /* Round to 4k */
back_size = ((back_size + 4096 - 1) / 4096) * 4096;
- xf86DrvMsg(pScreen->myNum, X_INFO, "back_size 2 : %d\n", back_size);
}
sysmem_size = pScrn->videoRam * 1024;
@@ -407,15 +417,18 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
else {
sysmem_size = sysmem_size - 2*back_size;
}
- xf86DrvMsg(pScreen->myNum, X_INFO, "sysmem_size : %d\n", sysmem_size);
-
- sysmem_size -= 4096;
- if (sysmem_size > ((48*1024*1024) - 1) ) {
- sysmem_size = (48*1024*1024) - (2*4096);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "User requested more memory then fits in the agp aperture\n"
+
+ if(sysmem_size > 48*1024*1024) {
+ sysmem_size = 48*1024*1024;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "User requested more memory then fits in the agp aperture\n"
"Truncating to %d bytes of memory\n",
sysmem_size);
}
+
+ sysmem_size -= 4096; /* remove 4k for the hw cursor */
+
pI810->SysMem.Start = 0;
pI810->SysMem.Size = sysmem_size;
pI810->SysMem.End = sysmem_size;
@@ -425,11 +438,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
if (dcacheHandle != 0) {
/* The Z buffer is always aligned to the 48 mb mark in the aperture */
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "dcacheHandle : %p, aligned to : %lx\n",
- dcacheHandle, 48*1024*1024);
-
- if (drmAgpBind(pI810->drmSubFD, dcacheHandle, 48*1024*1024) == 0) {
+ if(drmAgpBind(pI810->drmSubFD, dcacheHandle, 48*1024*1024) == 0) {
xf86memset (&pI810->DcacheMem, 0, sizeof(I810MemRange));
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"GART: Found 4096K Z buffer memory\n");
@@ -459,8 +468,6 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
if (agpHandle != 0) {
/* The backbuffer is always aligned to the 56 mb mark in the aperture */
- xf86DrvMsg(pScreen->myNum, X_INFO, "agpHandle : %p, aligned to : %lx\n",
- agpHandle, 56*1024*1024);
if(drmAgpBind(pI810->drmSubFD, agpHandle, 56*1024*1024) == 0) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Bound backbuffer memory\n");
@@ -488,10 +495,6 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
pI810->zHandle = agpHandle;
if(agpHandle != 0) {
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "agpHandle : %p, aligned to : %lx\n", dcacheHandle,
- 48*1024*1024);
-
if(drmAgpBind(pI810->drmSubFD, agpHandle, 48*1024*1024) == 0) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bound depthbuffer memory\n");
pI810->DepthBuffer.Start = 48*1024*1024;
@@ -515,7 +518,6 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
/* Now allocate and bind the agp space. This memory will include the
* regular framebuffer as well as texture memory.
*/
-
drmAgpAlloc(pI810->drmSubFD, sysmem_size, 0, NULL, &agpHandle);
if (agpHandle == 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAgpAlloc failed\n");
@@ -542,7 +544,6 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
"GART: Allocated 4K for mouse cursor image\n");
pI810->CursorStart = tom;
tom += 4096;
- xf86DrvMsg(pScreen->myNum, X_INFO, "tom : %lx\n", tom);
}
else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: cursor bind failed\n");
@@ -554,28 +555,21 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
pI810->CursorPhysical = 0;
}
- ErrorF("i : %d pI810->DepthBuffer %x\n", pitch_idx, pI810->DepthBuffer);
-
I810SetTiledMemory(pScrn, 1,
pI810->DepthBuffer.Start,
i810_pitches[pitch_idx],
8*1024*1024);
- ErrorF("i : %d\n", pitch_idx);
I810SetTiledMemory(pScrn, 2,
pI810->BackBuffer.Start,
i810_pitches[pitch_idx],
8*1024*1024);
- ErrorF("i : %d\n", pitch_idx);
pI810->auxPitch = i810_pitches[pitch_idx];
pI810->auxPitchBits = i810_pitch_flags[pitch_idx];
-
pI810->SavedDcacheMem = pI810->DcacheMem;
-
pI810DRI->backbufferSize = pI810->BackBuffer.Size;
- xf86DrvMsg(pScreen->myNum, X_INFO, "Backbuffer map : %lx\n",
- pI810->BackBuffer.Start);
+
if (drmAddMap(pI810->drmSubFD, (drmHandle)pI810->BackBuffer.Start,
pI810->BackBuffer.Size, DRM_AGP, 0,
&pI810DRI->backbuffer) < 0) {
@@ -584,8 +578,6 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
return FALSE;
}
- xf86DrvMsg(pScreen->myNum, X_INFO, "Depth map : %lx\n",
- pI810->DepthBuffer.Start);
pI810DRI->depthbufferSize = pI810->DepthBuffer.Size;
if (drmAddMap(pI810->drmSubFD, (drmHandle)pI810->DepthBuffer.Start,
pI810->DepthBuffer.Size, DRM_AGP, 0,
@@ -624,7 +616,6 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
pI810DRI->agp_buffers = pI810->buffer_map;
pI810DRI->agp_buf_size = pI810->BufferMem.Size;
- ErrorF("Ring map : %lx\n", pI810->LpRing.mem.Start);
if (drmAddMap(pI810->drmSubFD, (drmHandle)pI810->LpRing.mem.Start,
pI810->LpRing.mem.Size, DRM_AGP, 0,
&pI810->ring_map) < 0) {
@@ -636,8 +627,6 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
/* Use the rest of memory for textures. */
pI810DRI->textureSize = pI810->SysMem.Size;
- ErrorF("INITIAL texsize: %x\n", pI810DRI->textureSize);
-
i = mylog2(pI810DRI->textureSize / I810_NR_TEX_REGIONS);
if (i < I810_LOG_MIN_TEX_REGION_SIZE)
@@ -646,18 +635,15 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
pI810DRI->logTextureGranularity = i;
pI810DRI->textureSize = (pI810DRI->textureSize >> i) << i; /* truncate */
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "REDUCED texsize: %x (i: %d)\n", pI810DRI->textureSize, i);
-
- if (pI810DRI->textureSize < 512*1024) {
- xf86DrvMsg(pScreen->myNum, X_ERROR, "Less then 512k for textures\n");
+ if(pI810DRI->textureSize < 512*1024) {
+ ErrorF("Less then 512k for textures\n");
DRICloseScreen(pScreen);
+ return FALSE;
}
I810AllocLow( &(pI810->TexMem), &(pI810->SysMem),
pI810DRI->textureSize);
- ErrorF("Texture map : %lx\n", pI810->TexMem.Start);
if (drmAddMap(pI810->drmSubFD, (drmHandle)pI810->TexMem.Start,
pI810->TexMem.Size, DRM_AGP, 0,
&pI810DRI->textures) < 0) {
@@ -666,7 +652,6 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
return FALSE;
}
- ErrorF("pI810->BufferMem.Start : %lx\n", pI810->BufferMem.Start);
if((bufs = drmAddBufs(pI810->drmSubFD,
I810_DMA_BUF_NR,
I810_DMA_BUF_SZ,
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c
index 3db1809ae..6d4c8aafb 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c
@@ -1028,7 +1028,6 @@ DoRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, I810RegPtr i810Reg,
pI810 = I810PTR(pScrn);
hwp = VGAHWPTR(pScrn);
-
if (I810_DEBUG&DEBUG_VERBOSE_VGA) {
ErrorF("Setting mode in I810Restore:\n");
i810PrintMode( vgaReg, i810Reg );
@@ -1094,7 +1093,7 @@ DoRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, I810RegPtr i810Reg,
temp &= ~INTERLACE_ENABLE;
temp |= i810Reg->InterlaceControl;
hwp->writeCrtc(hwp, INTERLACE_CNTL, temp);
-
+
temp=pI810->readControl(pI810, GRX, ADDRESS_MAPPING);
temp &= 0xE0; /* Save reserved bits 7:5 */
temp |= i810Reg->AddressMapping;
@@ -1532,14 +1531,6 @@ I810AllocateFront(ScrnInfoPtr pScrn) {
pI810->FbMemBox.y2 *
pI810->cpp) + 4095) & ~4095);
- fprintf(stderr, "Framebuffer %x, size %x\n",
- pI810->FrontBuffer.Start,
- pI810->FrontBuffer.Size);
-
- fprintf(stderr, "DisplayWidth %x, virtualX %x\n",
- pScrn->displayWidth,
- pScrn->virtualX);
-
xf86memset( &(pI810->LpRing), 0, sizeof( I810RingBuffer ) );
if(I810AllocLow( &(pI810->LpRing.mem), &(pI810->SysMem), 16*4096 )) {
if (I810_DEBUG & DEBUG_VERBOSE_MEMORY)
@@ -1728,13 +1719,6 @@ I810ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
}
#endif
- ErrorF("InitFB box: %d,%d-%d,%d virt: %d,%d\n",
- pI810->FbMemBox.x1,
- pI810->FbMemBox.y1,
- pI810->FbMemBox.x2,
- pI810->FbMemBox.y2,
- pScrn->virtualX,
- pScrn->virtualY);
if (!xf86InitFBManager(pScreen, &(pI810->FbMemBox))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -1890,9 +1874,10 @@ I810LeaveVT(int scrnIndex, int flags) {
pI810->LockHeld = 1;
}
#endif
-
- I810RefreshRing( pScrn );
- I810Sync( pScrn );
+ if(pI810->AccelInfoRec != NULL) {
+ I810RefreshRing( pScrn );
+ I810Sync( pScrn );
+ }
I810Restore(pScrn);
vgaHWLock(hwp);
}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_memory.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_memory.c
index 2cedd9682..f499ffa2d 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_memory.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_memory.c
@@ -46,7 +46,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "i810.h"
#include "i810_reg.h"
+#ifdef linux
#include <linux/agpgart.h>
+#endif
int I810AllocLow( I810MemRange *result, I810MemRange *pool, int size )
{
@@ -83,6 +85,7 @@ extern int xf86errno;
int I810AllocateGARTMemory( ScrnInfoPtr pScrn )
{
+#ifdef linux
struct _agp_info agpinf;
struct _agp_bind bind;
struct _agp_allocate alloc;
@@ -220,18 +223,23 @@ int I810AllocateGARTMemory( ScrnInfoPtr pScrn )
return TRUE;
+#else
+ return FALSE;
+#endif
}
void I810FreeGARTMemory( ScrnInfoPtr pScrn )
{
+#ifdef linux
I810Ptr pI810 = I810PTR(pScrn);
if (pI810->gartfd != -1) {
xf86close( pI810->gartfd );
pI810->gartfd = -1;
}
+#endif
}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c
index ffa073561..7f91b6630 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c
@@ -502,10 +502,8 @@ Bool MGADRIScreenInit(ScreenPtr pScreen)
pMGADRI->chipset = MGA_CARD_TYPE_G400;
break;
case PCI_CHIP_MGAG200:
-#if 0
pMGADRI->chipset = MGA_CARD_TYPE_G200;
break;
-#endif
case PCI_CHIP_MGAG200_PCI:
default:
xf86DrvMsg(pScreen->myNum, X_ERROR,
@@ -561,29 +559,37 @@ Bool MGADRIScreenInit(ScreenPtr pScreen)
pMGADRI->textureSize = (pMGADRI->textureSize >> i) << i; /* truncate */
- /* Calculate similar constants for AGP texture space
- */
- i = mylog2(pMGADRI->agpSize / MGA_NR_TEX_REGIONS);
- if (i < MGA_LOG_MIN_TEX_REGION_SIZE)
- i = MGA_LOG_MIN_TEX_REGION_SIZE;
-
- pMGADRI->logAgpTextureGranularity = i;
- pMGADRI->agpTextureSize = (pMGADRI->agpSize >> i) << i;
-
-
/* Here is where we need to do initialization of the dma engine */
- if ((bufs = drmAddBufs(pMGA->drmSubFD,
+ if((bufs = drmAddBufs(pMGA->drmSubFD,
MGA_DMA_BUF_NR,
MGA_DMA_BUF_SZ,
DRM_AGP_BUFFER,
- init_offset)) <= 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[drm] failure adding %d %d byte DMA buffers\n",
- MGA_DMA_BUF_NR,
- MGA_DMA_BUF_SZ);
- DRICloseScreen(pScreen);
- return FALSE;
+ init_offset)) <= 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] failure adding %d %d byte DMA buffers\n",
+ MGA_DMA_BUF_NR,
+ MGA_DMA_BUF_SZ);
+ DRICloseScreen(pScreen);
+ return FALSE;
}
+
+ pMGADRI->agpBufferOffset = init_offset + pMGADRIServer->agp_private;
+
+ /* Calculate texture constants for AGP texture space
+ */
+ {
+ CARD32 agpTextureOffset = MGA_DMA_BUF_SZ * MGA_DMA_BUF_NR;
+ CARD32 agpTextureSize = pMGADRI->agpSize - agpTextureOffset;
+
+ i = mylog2(agpTextureSize / MGA_NR_TEX_REGIONS);
+ if (i < MGA_LOG_MIN_TEX_REGION_SIZE)
+ i = MGA_LOG_MIN_TEX_REGION_SIZE;
+
+ pMGADRI->logAgpTextureGranularity = i;
+ pMGADRI->agpTextureSize = (agpTextureSize >> i) << i;
+ pMGADRI->agpTextureOffset = agpTextureOffset;
+ }
+
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"[drm] added %d %d byte DMA buffers\n",
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h
index 7196bc954..b8518ee89 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h
@@ -4,9 +4,11 @@
#define _MGA_DRI_
#include <xf86drm.h>
-#include "mga_drm_public.h"
+#include <xf86drmMga.h>
-typedef struct _mga_dri_server_private {
+#define MGA_MAX_DRAWABLES 256
+
+typedef struct {
int reserved_map_agpstart;
int reserved_map_idx;
int buffer_map_idx;
@@ -17,6 +19,7 @@ typedef struct _mga_dri_server_private {
int sgram;
unsigned long agpMode;
unsigned long agpHandle;
+ Bool agpAcquired;
drmHandle agp_private;
drmSize agpSizep;
drmAddress agpBase;
@@ -24,27 +27,115 @@ typedef struct _mga_dri_server_private {
drmHandle regs;
drmSize regsSize;
drmAddress regsMap;
- mgaWarpIndex WarpIndex[MGA_MAX_WARP_PIPES];
+ drmMgaWarpIndex WarpIndex[MGA_MAX_WARP_PIPES];
drmBufMapPtr drmBufs;
CARD8 *agp_map;
-} MGADRIServerPrivate, *MGADRIServerPrivatePtr;
+} MGADRIServerPrivateRec, *MGADRIServerPrivatePtr;
typedef struct {
- int deviceID;
- int width;
- int height;
- int mem;
- int cpp;
- int stride;
- int fbOffset;
- int backOffset;
- int depthOffset;
- int textureOffset;
- int textureSize;
- drmHandle agp;
- drmSize agpSize;
+ int chipset;
+ int width;
+ int height;
+ int mem;
+ int cpp;
+ unsigned int frontOffset;
+ unsigned int frontPitch;
+
+ unsigned int backOffset;
+ unsigned int backPitch;
+
+ unsigned int depthOffset;
+ unsigned int depthPitch;
+
+ unsigned int textureOffset;
+ unsigned int textureSize;
+ int logTextureGranularity;
+
+ /* Allow calculation of setup dma addresses.
+ */
+ unsigned int agpBufferOffset;
+
+ unsigned int agpTextureOffset;
+ unsigned int agpTextureSize;
+ int logAgpTextureGranularity;
+
+ /* Redundant?
+ */
+ unsigned int frontOrg;
+ unsigned int backOrg;
+ unsigned int depthOrg;
+
+ unsigned int mAccess;
+
+ drmHandle agp;
+ drmSize agpSize;
} MGADRIRec, *MGADRIPtr;
+/* WARNING: Do not change the SAREA structure without changing the kernel
+ * as well */
+typedef struct {
+ unsigned char next, prev;
+ unsigned char in_use;
+ unsigned int age;
+} MGATexRegionRec, *MGATexRegionPtr;
+
+typedef struct {
+ /* The channel for communication of state information to the kernel
+ * on firing a vertex dma buffer.
+ */
+ unsigned int ContextState[MGA_CTX_SETUP_SIZE];
+ unsigned int ServerState[MGA_2D_SETUP_SIZE];
+ unsigned int TexState[2][MGA_TEX_SETUP_SIZE];
+ unsigned int WarpPipe;
+ unsigned int dirty;
+
+ unsigned int nbox;
+ XF86DRIClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS];
+
+ /* Information about the most recently used 3d drawable. The
+ * client fills in the req_* fields, the server fills in the
+ * exported_ fields and puts the cliprects into boxes, above.
+ *
+ * The client clears the exported_drawable field before
+ * clobbering the boxes data.
+ */
+ unsigned int req_drawable; /* the X drawable id */
+ unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */
+
+ unsigned int exported_drawable;
+ unsigned int exported_index;
+ unsigned int exported_stamp;
+ unsigned int exported_buffers;
+ unsigned int exported_nfront;
+ unsigned int exported_nback;
+ int exported_back_x, exported_front_x, exported_w;
+ int exported_back_y, exported_front_y, exported_h;
+ XF86DRIClipRectRec exported_boxes[MGA_NR_SAREA_CLIPRECTS];
+
+ /* Counters for aging textures and for client-side throttling.
+ */
+ unsigned int last_enqueue; /* last time a buffer was enqueued */
+ unsigned int last_dispatch; /* age of the most recently dispatched buffer */
+ unsigned int last_quiescent; /* */
+
+ /* LRU lists for texture memory in agp space and on the card */
+
+ MGATexRegionRec texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1];
+ unsigned int texAge[MGA_NR_TEX_HEAPS];
+ /* Mechanism to validate card state.
+ */
+ int ctxOwner;
+} MGASAREARec, *MGASAREAPtr;
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} MGAConfigPrivRec, *MGAConfigPrivPtr;
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} MGADRIContextRec, *MGADRIContextPtr;
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/r128/Imakefile
index e3f7178bf..8f0f33a35 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/Imakefile
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/Imakefile
@@ -6,9 +6,16 @@ XCOMM
#define IHaveModules
#include <Server.tmpl>
-SRCS = r128_driver.c r128_cursor.c r128_accel.c # r128_i2c.c
+#if BuildXF86DRI
+DRISRCS = r128_dri.c
+DRIOBJS = r128_dri.o
+DRIINCLUDES = -I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri
+DRIDEFINES = $(GLX_DEFINES)
+#endif
+
+SRCS = r128_driver.c r128_cursor.c r128_accel.c $(DRISRCS) # r128_i2c.c
-OBJS = r128_driver.o r128_cursor.o r128_accel.o # r128_i2c.o
+OBJS = r128_driver.o r128_cursor.o r128_accel.o $(DRIOBJS) # r128_i2c.o
#if defined(XF86DriverSDK)
INCLUDES = -I. -I../../include
@@ -22,9 +29,12 @@ INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
-I$(XF86SRC)/ddc -I$(XF86SRC)/i2c -I$(XF86OSSRC)/vbe \
-I$(XF86SRC)/int10 -I$(SERVERSRC)/Xext \
-I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
- -I$(EXTINCSRC) -I$(XF86SRC)/xf24_32bpp
+ -I$(EXTINCSRC) -I$(XF86SRC)/xf24_32bpp \
+ $(DRIINCLUDES)
#endif
+DEFINES = $(DRIDEFINES)
+
#if MakeHasPosixVariableSubstitutions
SubdirLibraryRule($(OBJS))
#endif
@@ -49,5 +59,10 @@ InstallDriverSDKNonExecFile(r128_cursor.c,$(DRIVERSDKDIR)/drivers/r128)
InstallDriverSDKNonExecFile(r128_driver.c,$(DRIVERSDKDIR)/drivers/r128)
InstallDriverSDKNonExecFile(r128_reg.h,$(DRIVERSDKDIR)/drivers/r128)
+InstallDriverSDKNonExecFile(r128_dri.c,$(DRIVERSDKDIR)/drivers/r128)
+InstallDriverSDKNonExecFile(r128_dri.h,$(DRIVERSDKDIR)/drivers/r128)
+InstallDriverSDKNonExecFile(r128_dripriv.h,$(DRIVERSDKDIR)/drivers/r128)
+InstallDriverSDKNonExecFile(r128_sarea.h,$(DRIVERSDKDIR)/drivers/r128)
+
InstallDriverSDKObjectModule(r128,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h
index d5d120153..acb04f96e 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h
@@ -1,8 +1,8 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h,v 1.8 2000/02/23 04:47:18 martin Exp $ */
/**************************************************************************
-Copyright 1999 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -40,6 +40,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R128_TIMEOUT 2000000 /* Fall out of wait loops after this count */
#define R128_MMIOSIZE 0x80000
+ /* R128_NAME is used for the server-side
+ ddx driver, the client-side DRI driver,
+ and the kernel-level DRM driver. */
#define R128_NAME "r128"
#define R128_VERSION_MAJOR 3
#define R128_VERSION_MINOR 0
@@ -157,7 +160,7 @@ typedef struct {
unsigned char *FB; /* Map of frame buffer */
CARD32 MemCntl;
- CARD32 BusCntl;
+ CARD32 BusCntl;
unsigned long FbMapSize; /* Size of frame buffer, in bytes */
int Flags; /* Saved copy of mode flags */
@@ -168,6 +171,8 @@ typedef struct {
R128SaveRec ModeReg; /* Current mode */
Bool (*CloseScreen)(int, ScreenPtr);
+ Bool PaletteSavedOnVT; /* Palette saved on last VT switch */
+
I2CBusPtr i2c;
XAAInfoRecPtr accel;
xf86CursorInfoPtr cursor;
@@ -199,8 +204,98 @@ typedef struct {
int scanline_words;
int scanline_direct;
int scanline_bpp; /* Only used for ImageWrite */
+
+#ifdef XF86DRI
+ Bool directRenderingEnabled;
+ DRIInfoPtr pDRIInfo;
+ int drmFD;
+ int numVisualConfigs;
+ __GLXvisualConfig *pVisualConfigs;
+ R128ConfigPrivPtr pVisualConfigsPriv;
+
+ drmHandle fbHandle;
+
+ drmSize registerSize;
+ drmHandle registerHandle;
+
+ Bool IsPCI; /* Current card is a PCI card */
+
+ drmSize agpSize;
+ drmHandle agpMemHandle; /* Handle from drmAgpAlloc */
+ unsigned long agpOffset;
+ unsigned char *AGP; /* Map */
+ int agpMode;
+
+ Bool CCEInUse; /* CCE is currently active */
+ int CCEMode; /* CCE mode that server/clients use */
+ int CCEFifoSize; /* Size of the CCE command FIFO */
+ Bool CCESecure; /* CCE security enabled */
+ int CCEusecTimeout; /* CCE timeout in usecs */
+ Bool CCE2D; /* CCE is used for X server 2D prims */
+
+ /* CCE ring buffer data */
+ unsigned long ringStart; /* Offset into AGP space */
+ drmHandle ringHandle; /* Handle from drmAddMap */
+ drmSize ringMapSize; /* Size of map */
+ int ringSize; /* Size of ring (in MB) */
+ unsigned char *ring; /* Map */
+ int ringSizeLog2QW;
+
+ unsigned long ringReadOffset; /* Offset into AGP space */
+ drmHandle ringReadPtrHandle; /* Handle from drmAddMap */
+ drmSize ringReadMapSize; /* Size of map */
+ unsigned char *ringReadPtr; /* Map */
+
+ /* CCE vertex buffer data */
+ unsigned long vbStart; /* Offset into AGP space */
+ drmHandle vbHandle; /* Handle from drmAddMap */
+ drmSize vbMapSize; /* Size of map */
+ int vbSize; /* Size of vert bufs (in MB) */
+ unsigned char *vb; /* Map */
+ int vbBufSize; /* Size of individual vert buf */
+ int vbNumBufs; /* Number of vert bufs */
+ drmBufMapPtr vbBufs; /* Buffer map */
+
+ /* CCE indirect buffer data */
+ unsigned long indStart; /* Offset into AGP space */
+ drmHandle indHandle; /* Handle from drmAddMap */
+ drmSize indMapSize; /* Size of map */
+ int indSize; /* Size of indirect bufs (in MB) */
+ unsigned char *ind; /* Map */
+
+ /* CCE AGP Texture data */
+ unsigned long agpTexStart; /* Offset into AGP space */
+ drmHandle agpTexHandle; /* Handle from drmAddMap */
+ drmSize agpTexMapSize; /* Size of map */
+ int agpTexSize; /* Size of AGP tex space (in MB) */
+ unsigned char *agpTex; /* Map */
+ int log2AGPTexGran;
+
+ /* DRI screen private data */
+ int fbX;
+ int fbY;
+ int backX;
+ int backY;
+ int depthX;
+ int depthY;
+ int textureX;
+ int textureY;
+ int textureSize;
+ int log2TexGran;
+#endif
} R128InfoRec, *R128InfoPtr;
+#define R128WaitForFifo(pScrn, entries) \
+do { \
+ if (info->fifo_slots < entries) R128WaitForFifoFunction(pScrn, entries); \
+ info->fifo_slots -= entries; \
+} while (0)
+
+extern void R128WaitForFifoFunction(ScrnInfoPtr pScrn, int entries);
+extern void R128WaitForIdle(ScrnInfoPtr pScrn);
+extern void R128EngineReset(ScrnInfoPtr pScrn);
+extern void R128EngineFlush(ScrnInfoPtr pScrn);
+
extern int INPLL(ScrnInfoPtr pScrn, int addr);
extern void R128WaitForVerticalSync(ScrnInfoPtr pScrn);
@@ -208,4 +303,16 @@ extern Bool R128AccelInit(ScreenPtr pScreen);
extern void R128EngineInit(ScrnInfoPtr pScrn);
extern Bool R128CursorInit(ScreenPtr pScreen);
+extern int R128MinBits(int val);
+
+#ifdef XF86DRI
+extern Bool R128DRIScreenInit(ScreenPtr pScreen);
+extern void R128DRICloseScreen(ScreenPtr pScreen);
+extern Bool R128DRIFinishScreenInit(ScreenPtr pScreen);
+extern void R128CCEStart(ScrnInfoPtr pScrn);
+extern void R128CCEStop(ScrnInfoPtr pScrn);
+extern void R128CCEResetRing(ScrnInfoPtr pScrn);
+extern void R128CCEWaitForIdle(ScrnInfoPtr pScrn);
+#endif
+
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c
index 5b0223661..f42569767 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c
@@ -1,8 +1,8 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c,v 1.7 2000/02/23 04:47:18 martin Exp $ */
/**************************************************************************
-Copyright 1999 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -95,6 +95,19 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
/* DDC support */
#include "xf86DDC.h"
+ /* DRI support */
+#ifdef XF86DRI
+#include "GL/glxint.h"
+#include "xf86drm.h"
+#include "sarea.h"
+#define _XF86DRI_SERVER_
+#include "xf86dri.h"
+#include "dri.h"
+#include "r128_dri.h"
+#include "r128_dripriv.h"
+#include "r128_sarea.h"
+#endif
+
/* Driver data structures */
#include "r128.h"
#include "r128_reg.h"
@@ -122,7 +135,7 @@ static struct {
};
/* Flush all dirty data in the Pixel Cache to memory. */
-static void R128EngineFlush(ScrnInfoPtr pScrn)
+void R128EngineFlush(ScrnInfoPtr pScrn)
{
int i;
R128MMIO_VARS();
@@ -134,11 +147,12 @@ static void R128EngineFlush(ScrnInfoPtr pScrn)
}
/* Reset graphics card to known state. */
-static void R128EngineReset(ScrnInfoPtr pScrn)
+void R128EngineReset(ScrnInfoPtr pScrn)
{
- CARD32 clock_cntl_index;
- CARD32 mclk_cntl;
- CARD32 gen_reset_cntl;
+ R128InfoPtr info = R128PTR(pScrn);
+ CARD32 clock_cntl_index;
+ CARD32 mclk_cntl;
+ CARD32 gen_reset_cntl;
R128MMIO_VARS();
R128EngineFlush(pScrn);
@@ -158,17 +172,15 @@ static void R128EngineReset(ScrnInfoPtr pScrn)
OUTPLL(R128_MCLK_CNTL, mclk_cntl);
OUTREG(R128_CLOCK_CNTL_INDEX, clock_cntl_index);
OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl);
-}
-#define R128WaitForFifo(pScrn, entries) \
-do { \
- if (info->fifo_slots < entries) R128WaitForFifoFunction(pScrn, entries); \
- info->fifo_slots -= entries; \
-} while (0)
+#ifdef XF86DRI
+ if (R128CCE_USE_RING_BUFFER(info->CCEMode)) R128CCEResetRing(pScrn);
+#endif
+}
/* The FIFO has 64 slots. This routines waits until at least `entries' of
these slots are empty. */
-static void R128WaitForFifoFunction(ScrnInfoPtr pScrn, int entries)
+void R128WaitForFifoFunction(ScrnInfoPtr pScrn, int entries)
{
R128InfoPtr info = R128PTR(pScrn);
int i;
@@ -186,15 +198,19 @@ static void R128WaitForFifoFunction(ScrnInfoPtr pScrn, int entries)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"FIFO timed out, resetting engine...\n");
R128EngineReset(pScrn);
+#if XF86DRI
+ if (info->CCE2D) R128CCEStart(pScrn);
+#endif
}
}
/* Wait for the graphics engine to be completely idle: the FIFO has
drained, the Pixel Cache is flushed, and the engine is idle. This is a
standard "sync" function that will make the hardware "quiescent". */
-static void R128WaitForIdle(ScrnInfoPtr pScrn)
+void R128WaitForIdle(ScrnInfoPtr pScrn)
{
- int i;
+ R128InfoPtr info = R128PTR(pScrn);
+ int i;
R128MMIO_VARS();
R128WaitForFifoFunction(pScrn, 64);
@@ -213,6 +229,9 @@ static void R128WaitForIdle(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Idle timed out, resetting engine...\n");
R128EngineReset(pScrn);
+#if XF86DRI
+ if (info->CCE2D) R128CCEStart(pScrn);
+#endif
}
}
@@ -966,19 +985,33 @@ void R128EngineInit(ScrnInfoPtr pScrn)
OUTREG(R128_DP_SRC_BKGD_CLR, 0x00000000);
OUTREG(R128_DP_WRITE_MASK, 0xffffffff);
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ OUTREGP(R128_DP_DATATYPE,
+ R128_HOST_BIG_ENDIAN_EN, ~R128_HOST_BIG_ENDIAN_EN);
+#else
+ OUTREGP(R128_DP_DATATYPE, 0, ~R128_HOST_BIG_ENDIAN_EN);
+#endif
+
R128WaitForIdle(pScrn);
}
-/* Initialize XAA for supported acceleration and also initialize the
- graphics hardware for acceleration. */
-Bool R128AccelInit(ScreenPtr pScreen)
+#ifdef XF86DRI
+ /* FIXME: When direct rendering is enabled, we should use the CCE to
+ draw 2D commands */
+static void R128CCEAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a)
{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- XAAInfoRecPtr a;
+ a->Flags = 0;
+
+ /* Sync */
+ a->Sync = R128CCEWaitForIdle;
+
+}
+#endif
+
+static void R128MMIOAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a)
+{
+ R128InfoPtr info = R128PTR(pScrn);
- if (!(a = info->accel = XAACreateInfoRec())) return FALSE;
-
a->Flags = (PIXMAP_CACHE
| OFFSCREEN_PIXMAPS
| LINEAR_FRAMEBUFFER);
@@ -1065,7 +1098,26 @@ Bool R128AccelInit(ScreenPtr pScreen)
| SCANLINE_PAD_DWORD
| SYNC_AFTER_IMAGE_WRITE);
#endif
-
+}
+
+/* Initialize XAA for supported acceleration and also initialize the
+ graphics hardware for acceleration. */
+Bool R128AccelInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ R128InfoPtr info = R128PTR(pScrn);
+ XAAInfoRecPtr a;
+
+ if (!(a = info->accel = XAACreateInfoRec())) return FALSE;
+
+#ifdef XF86DRI
+ /* FIXME: When direct rendering is enabled, we should use the CCE to
+ draw 2D commands */
+ if (info->CCE2D) R128CCEAccelInit(pScrn, a);
+ else
+#endif
+ R128MMIOAccelInit(pScrn, a);
+
R128EngineInit(pScrn);
return XAAInit(pScreen, a);
}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_cursor.c
index a96872702..2667443d9 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_cursor.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_cursor.c
@@ -1,8 +1,8 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/r128_cursor.c,v 1.6 2000/03/06 22:59:26 dawes Exp $ */
/**************************************************************************
-Copyright 1999 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -60,6 +60,19 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
/* DDC support */
#include "xf86DDC.h"
+ /* DRI support */
+#ifdef XF86DRI
+#include "GL/glxint.h"
+#include "xf86drm.h"
+#include "sarea.h"
+#define _XF86DRI_SERVER_
+#include "xf86dri.h"
+#include "dri.h"
+#include "r128_dri.h"
+#include "r128_dripriv.h"
+#include "r128_sarea.h"
+#endif
+
/* Driver data structures */
#include "r128.h"
#include "r128_reg.h"
@@ -92,16 +105,19 @@ static void R128SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
(xorigin,yorigin). */
static void R128SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
- R128InfoPtr info = R128PTR(pScrn);
- int xorigin = 0;
- int yorigin = 0;
- int total_y = pScrn->frameY1 - pScrn->frameY0;
+ R128InfoPtr info = R128PTR(pScrn);
+ xf86CursorInfoPtr cursor = info->cursor;
+ int xorigin = 0;
+ int yorigin = 0;
+ int total_y = pScrn->frameY1 - pScrn->frameY0;
R128MMIO_VARS();
- if (x < 0) xorigin = -x;
- if (y < 0) yorigin = -y;
- if (y > total_y) y = total_y;
- if (info->Flags & V_DBLSCAN) y *= 2;
+ if (x < 0) xorigin = -x;
+ if (y < 0) yorigin = -y;
+ if (y > total_y) y = total_y;
+ if (info->Flags & V_DBLSCAN) y *= 2;
+ if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1;
+ if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1;
OUTREG(R128_CUR_HORZ_VERT_OFF, R128_CUR_LOCK | (xorigin << 16) | yorigin);
OUTREG(R128_CUR_HORZ_VERT_POSN, (R128_CUR_LOCK
@@ -126,47 +142,58 @@ static void R128LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image)
#if X_BYTE_ORDER == X_BIG_ENDIAN
switch(info->pixel_bytes) {
- case 4:
- case 3:
- for (y = 0; y < 64; y++) {
- P_SWAP32(d,s);
- d++; s++;
- P_SWAP32(d,s);
- d++; s++;
- P_SWAP32(d,s);
- d++; s++;
- P_SWAP32(d,s);
- d++; s++;
- }
- break;
- case 2:
- for (y = 0; y < 64; y++) {
- P_SWAP16(d,s);
- d++; s++;
- P_SWAP16(d,s);
- d++; s++;
- P_SWAP16(d,s);
- d++; s++;
- P_SWAP16(d,s);
- d++; s++;
- }
- break;
- default:
- for (y = 0; y < 64; y++) {
+ case 4:
+ case 3:
+ for (y = 0; y < 64; y++) {
+ P_SWAP32(d,s);
+ d++; s++;
+ P_SWAP32(d,s);
+ d++; s++;
+ P_SWAP32(d,s);
+ d++; s++;
+ P_SWAP32(d,s);
+ d++; s++;
+ }
+ break;
+ case 2:
+ for (y = 0; y < 64; y++) {
+ P_SWAP16(d,s);
+ d++; s++;
+ P_SWAP16(d,s);
+ d++; s++;
+ P_SWAP16(d,s);
+ d++; s++;
+ P_SWAP16(d,s);
+ d++; s++;
+ }
+ break;
+ default:
+ for (y = 0; y < 64; y++) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
- }
+ }
}
#else
- for (y = 0; y < 64; y++) {
+ for (y = 0; y < 64; y++) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
#endif
+
+ /* Set the area after the cursor to be all transparent so that we
+ won't display corrupted cursors on the screen */
+ for (y = 0; y < 64; y++) {
+ *d++ = 0xffffffff; /* The AND bits */
+ *d++ = 0xffffffff;
+ *d++ = 0x00000000; /* The XOR bits */
+ *d++ = 0x00000000;
+ }
+
+
OUTREG(R128_CRTC_GEN_CNTL, save);
}
@@ -204,6 +231,7 @@ Bool R128CursorInit(ScreenPtr pScreen)
FBAreaPtr fbarea;
int width;
int height;
+ int size;
if (!(cursor = info->cursor = xf86CreateCursorInfoRec())) return FALSE;
@@ -227,8 +255,9 @@ Bool R128CursorInit(ScreenPtr pScreen)
cursor->ShowCursor = R128ShowCursor;
cursor->UseHWCursor = R128UseHWCursor;
+ size = (cursor->MaxWidth/4) * cursor->MaxHeight;
width = pScrn->displayWidth;
- height = (1024 + 1023) / pScrn->displayWidth;
+ height = (size*2 + 1023) / pScrn->displayWidth;
fbarea = xf86AllocateOffscreenArea(pScreen,
width,
height,
@@ -246,7 +275,7 @@ Bool R128CursorInit(ScreenPtr pScreen)
info->cursor_start = R128_ALIGN((fbarea->box.x1
+ width * fbarea->box.y1)
* info->pixel_bytes, 16);
- info->cursor_end = info->cursor_start + 1024;
+ info->cursor_end = info->cursor_start + size;
}
R128TRACE(("R128CursorInit (0x%08x-0x%08x)\n",
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c
new file mode 100644
index 000000000..cb647d6b6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c
@@ -0,0 +1,1242 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Rickard E. Faith <faith@precisioninsight.com>
+ * Daryll Strauss <daryll@precisioninsight.com>
+ *
+ */
+
+
+ /* X and server generic header files */
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86RAC.h"
+#include "xf86cmap.h"
+#include "xf86fbman.h"
+
+ /* Backing store, software cursor, and
+ colormap initialization */
+#include "mibstore.h"
+#include "mipointer.h"
+#include "micmap.h"
+
+ /* CFB support */
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+
+ /* XAA and Cursor Support */
+#include "xaa.h"
+#include "xf86Cursor.h"
+
+ /* PCI support */
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+ /* DDC support */
+#include "xf86DDC.h"
+
+ /* DRI support */
+#include "GL/glxint.h"
+#include "GL/glxtokens.h"
+#include "xf86drm.h"
+#include "xf86drmR128.h"
+#include "sarea.h"
+#define _XF86DRI_SERVER_
+#include "xf86dri.h"
+#include "dri.h"
+#include "r128_dri.h"
+#include "r128_sarea.h"
+#include "r128_dripriv.h"
+
+ /* Driver data structures */
+#include "r128.h"
+#include "r128_reg.h"
+
+#define R128_WATERMARK_L 16
+#define R128_WATERMARK_M 8
+#define R128_WATERMARK_N 8
+#define R128_WATERMARK_K 128
+
+static int CCEFifoSlots = 0;
+
+#define R128CCEWaitForFifo(pScrn, entries) \
+do { \
+ if (CCEFifoSlots < entries) R128WaitForFifoFunction(pScrn, entries); \
+ CCEFifoSlots -= entries; \
+} while (0)
+
+/* Wait for at least `entries' slots are free. The actual number of
+ slots available is stored in info->CCEFifoSize. */
+static void R128CCEWaitForFifoFunction(ScrnInfoPtr pScrn, int entries)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+ int i;
+
+ for (;;) {
+ for (i = 0; i < R128_TIMEOUT; i++) {
+ CCEFifoSlots = INREG(R128_PM4_STAT) & R128_PM4_FIFOCNT_MASK;
+ if (CCEFifoSlots >= entries) return;
+ }
+ R128EngineReset(pScrn);
+ if (info->CCE2D) R128CCEStart(pScrn);
+ }
+}
+
+/* Wait until the CCE is completely idle: the FIFO has drained and the
+ CCE is idle. */
+void R128CCEWaitForIdle(ScrnInfoPtr pScrn)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+ int i;
+
+ if (!info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return;
+
+ if (R128CCE_USE_RING_BUFFER(info->CCEMode)) {
+ volatile CARD32 *r128RingReadPtr =
+ (volatile CARD32 *)(info->ringReadPtr);
+ R128SAREAPrivPtr pSAREAPriv;
+
+ OUTREGP(R128_PM4_BUFFER_DL_WPTR,
+ R128_PM4_BUFFER_DL_DONE, ~R128_PM4_BUFFER_DL_DONE);
+
+ pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScrn->pScreen);
+
+ for (;;) {
+ for (i = 0; i < R128_TIMEOUT; i++) {
+ if (*r128RingReadPtr == pSAREAPriv->ringWrite) {
+ int pm4stat = INREG(R128_PM4_STAT);
+ if ((pm4stat & R128_PM4_FIFOCNT_MASK) >= info->CCEFifoSize
+ && !(pm4stat & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE)))
+ return;
+ }
+ }
+ R128EngineReset(pScrn);
+ if (info->CCE2D) R128CCEStart(pScrn);
+ }
+ } else {
+ R128CCEWaitForFifoFunction(pScrn, info->CCEFifoSize);
+
+ for (;;) {
+ for (i = 0; i < R128_TIMEOUT; i++) {
+ if (!(INREG(R128_PM4_STAT)
+ & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) {
+ R128EngineFlush(pScrn);
+ return;
+ }
+ }
+ R128EngineReset(pScrn);
+ if (info->CCE2D) R128CCEStart(pScrn);
+ }
+ }
+}
+
+/* Reset the ring buffer status, if the engine was reset */
+void R128CCEResetRing(ScrnInfoPtr pScrn)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+ R128SAREAPrivPtr pSAREAPriv;
+ volatile CARD32 *r128RingReadPtr;
+
+ if (!info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return;
+
+ r128RingReadPtr = (volatile CARD32 *)(info->ringReadPtr);
+ pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScrn->pScreen);
+
+ OUTREG(R128_PM4_BUFFER_DL_WPTR, 0);
+ OUTREG(R128_PM4_BUFFER_DL_RPTR, 0);
+ pSAREAPriv->ringWrite = 0;
+ *r128RingReadPtr = 0;
+
+ /* Resetting the ring turns off the CCE */
+ info->CCEInUse = FALSE;
+}
+
+/* Start the CCE, but only if it is not already in use and the requested
+ mode is a CCE mode. The mode is stored in info->CCEMode. */
+void R128CCEStart(ScrnInfoPtr pScrn)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+
+ if (info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return;
+
+ R128WaitForIdle(pScrn);
+ OUTREG(R128_PM4_BUFFER_CNTL, info->CCEMode | info->ringSizeLog2QW);
+ (void)INREG(R128_PM4_BUFFER_ADDR); /* as per the sample code */
+ OUTREG(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN);
+ info->CCEInUse = TRUE;
+}
+
+/* Stop the CCE, but only if it is in use and the requested mode is not
+ the non-CCE mode. This function also flushes any outstanding
+ requests before switching modes.*/
+void R128CCEStop(ScrnInfoPtr pScrn)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+
+ if (!info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return;
+
+ R128CCEWaitForIdle(pScrn);
+ OUTREG(R128_PM4_MICRO_CNTL, 0);
+ OUTREG(R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4);
+ R128EngineReset(pScrn);
+ info->CCEInUse = FALSE;
+}
+
+/* Initialize the visual configs that are supported by the hardware.
+ These are combined with the visual configs that the indirect
+ rendering core supports, and the intersection is exported to the
+ client. */
+static Bool R128InitVisualConfigs(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ R128InfoPtr pR128 = R128PTR(pScrn);
+ int numConfigs = 0;
+ __GLXvisualConfig *pConfigs = 0;
+ R128ConfigPrivPtr pR128Configs = 0;
+ R128ConfigPrivPtr *pR128ConfigPtrs = 0;
+ int i, accum, stencil;
+
+ switch (pR128->pixel_code) {
+ case 8: /* 8bpp mode is not support */
+ case 15: /* FIXME */
+ case 24: /* FIXME */
+ return FALSE;
+
+#define R128_USE_ACCUM 1
+#define R128_USE_STENCIL 0 /* Only in 24 depth mode */
+
+ case 16:
+ numConfigs = 1;
+ if (R128_USE_ACCUM) numConfigs *= 2;
+
+ if (!(pConfigs
+ = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig),
+ numConfigs))) {
+ return FALSE;
+ }
+ if (!(pR128Configs
+ = (R128ConfigPrivPtr)xnfcalloc(sizeof(R128ConfigPrivRec),
+ numConfigs))) {
+ xfree(pConfigs);
+ return FALSE;
+ }
+ if (!(pR128ConfigPtrs
+ = (R128ConfigPrivPtr*)xnfcalloc(sizeof(R128ConfigPrivPtr),
+ numConfigs))) {
+ xfree(pConfigs);
+ xfree(pR128Configs);
+ return FALSE;
+ }
+
+ i = 0;
+ for (accum = 0; accum <= R128_USE_ACCUM; accum++) {
+ pR128ConfigPtrs[i] = &pR128Configs[i];
+
+ pConfigs[i].vid = -1;
+ pConfigs[i].class = -1;
+ pConfigs[i].rgba = TRUE;
+ pConfigs[i].redSize = 5;
+ pConfigs[i].greenSize = 6;
+ pConfigs[i].blueSize = 5;
+ pConfigs[i].redMask = 0x0000F800;
+ pConfigs[i].greenMask = 0x000007E0;
+ pConfigs[i].blueMask = 0x0000001F;
+
+ pConfigs[i].alphaMask = 0;
+ if (accum) { /* Simulated in software */
+ pConfigs[i].accumRedSize = 16;
+ pConfigs[i].accumGreenSize = 16;
+ pConfigs[i].accumBlueSize = 16;
+ pConfigs[i].accumAlphaSize = 0;
+ } else {
+ pConfigs[i].accumRedSize = 0;
+ pConfigs[i].accumGreenSize = 0;
+ pConfigs[i].accumBlueSize = 0;
+ pConfigs[i].accumAlphaSize = 0;
+ }
+ pConfigs[i].doubleBuffer = TRUE;
+ pConfigs[i].stereo = FALSE;
+ pConfigs[i].bufferSize = 16;
+ pConfigs[i].depthSize = 16;
+ pConfigs[i].stencilSize = 0;
+ pConfigs[i].auxBuffers = 0;
+ pConfigs[i].level = 0;
+ if (accum)
+ pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT;
+ else
+ pConfigs[i].visualRating = GLX_NONE_EXT;
+ pConfigs[i].transparentPixel = 0;
+ pConfigs[i].transparentRed = 0;
+ pConfigs[i].transparentGreen = 0;
+ pConfigs[i].transparentBlue = 0;
+ pConfigs[i].transparentAlpha = 0;
+ pConfigs[i].transparentIndex = 0;
+ i++;
+ }
+ break;
+ case 32:
+ numConfigs = 1;
+ if (R128_USE_ACCUM) numConfigs *= 2;
+ if (R128_USE_STENCIL) numConfigs *= 2;
+
+ if (!(pConfigs
+ = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig),
+ numConfigs))) {
+ return FALSE;
+ }
+ if (!(pR128Configs
+ = (R128ConfigPrivPtr)xnfcalloc(sizeof(R128ConfigPrivRec),
+ numConfigs))) {
+ xfree(pConfigs);
+ return FALSE;
+ }
+ if (!(pR128ConfigPtrs
+ = (R128ConfigPrivPtr*)xnfcalloc(sizeof(R128ConfigPrivPtr),
+ numConfigs))) {
+ xfree(pConfigs);
+ xfree(pR128Configs);
+ return FALSE;
+ }
+
+ i = 0;
+ for (accum = 0; accum <= R128_USE_ACCUM; accum++) {
+ for (stencil = 0; stencil <= R128_USE_STENCIL; stencil++) {
+ pR128ConfigPtrs[i] = &pR128Configs[i];
+
+ pConfigs[i].vid = -1;
+ pConfigs[i].class = -1;
+ pConfigs[i].rgba = TRUE;
+ pConfigs[i].redSize = 8;
+ pConfigs[i].greenSize = 8;
+ pConfigs[i].blueSize = 8;
+ pConfigs[i].redMask = 0x00FF0000;
+ pConfigs[i].greenMask = 0x0000FF00;
+ pConfigs[i].blueMask = 0x000000FF;
+
+ pConfigs[i].alphaMask = 0;
+ if (accum) { /* Simulated in software */
+ pConfigs[i].accumRedSize = 16;
+ pConfigs[i].accumGreenSize = 16;
+ pConfigs[i].accumBlueSize = 16;
+ pConfigs[i].accumAlphaSize = 0;
+ } else {
+ pConfigs[i].accumRedSize = 0;
+ pConfigs[i].accumGreenSize = 0;
+ pConfigs[i].accumBlueSize = 0;
+ pConfigs[i].accumAlphaSize = 0;
+ }
+ pConfigs[i].doubleBuffer = TRUE;
+ pConfigs[i].stereo = FALSE;
+ pConfigs[i].bufferSize = 24;
+ if (stencil) {
+ pConfigs[i].depthSize = 24;
+ pConfigs[i].stencilSize = 8;
+ } else {
+ pConfigs[i].depthSize = 32;
+ pConfigs[i].stencilSize = 0;
+ }
+ pConfigs[i].auxBuffers = 0;
+ pConfigs[i].level = 0;
+ if (accum)
+ pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT;
+ else
+ pConfigs[i].visualRating = GLX_NONE_EXT;
+ pConfigs[i].transparentPixel = 0;
+ pConfigs[i].transparentRed = 0;
+ pConfigs[i].transparentGreen = 0;
+ pConfigs[i].transparentBlue = 0;
+ pConfigs[i].transparentAlpha = 0;
+ pConfigs[i].transparentIndex = 0;
+ i++;
+ }
+ }
+ break;
+ }
+
+ pR128->numVisualConfigs = numConfigs;
+ pR128->pVisualConfigs = pConfigs;
+ pR128->pVisualConfigsPriv = pR128Configs;
+ GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pR128ConfigPtrs);
+ return TRUE;
+}
+
+/* Create the Rage 128-specific context information */
+static Bool R128CreateContext(ScreenPtr pScreen, VisualPtr visual,
+ drmContext hwContext, void *pVisualConfigPriv,
+ DRIContextType contextStore)
+{
+ /* Nothing yet */
+ return TRUE;
+}
+
+/* Destroy the Rage 128-specific context information */
+static void R128DestroyContext(ScreenPtr pScreen, drmContext hwContext,
+ DRIContextType contextStore)
+{
+ /* Nothing yet */
+}
+
+/* Called when the X server is woken up to allow the last client's
+ context to be saved and the X server's context to be loaded. This is
+ not necessary for the Rage 128 since the client detects when it's
+ context is not currently loaded and then load's it itself. Since the
+ registers to start and stop the CCE are privileged, only the X server
+ can start/stop the engine. */
+static void R128EnterServer(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ R128InfoPtr pR128 = R128PTR(pScrn);
+
+ if (pR128->accel) pR128->accel->NeedToSync = TRUE;
+
+#if 1
+ if (!pR128->CCE2D) R128CCEStop(pScrn);
+#else
+ if (pR128->CCE2D) R128CCEWaitForIdle(pScrn);
+ else R128CCEStop(pScrn);
+#endif
+}
+
+/* Called when the X server goes to sleep to allow the X server's
+ context to be saved and the last client's context to be loaded. This
+ is not necessary for the Rage 128 since the client detects when it's
+ context is not currently loaded and then load's it itself. Since the
+ registers to start and stop the CCE are privileged, only the X server
+ can start/stop the engine. */
+static void R128LeaveServer(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ R128InfoPtr pR128 = R128PTR(pScrn);
+
+#if 1
+ if (!pR128->CCE2D) R128CCEStart(pScrn);
+#else
+ if (pR128->CCE2D) R128CCEWaitForIdle(pScrn);
+ else R128CCEStart(pScrn);
+#endif
+}
+
+/* Contexts can be swapped by the X server if necessary. This callback
+ is currently only used to perform any functions necessary when
+ entering or leaving the X server, and in the future might not be
+ necessary. */
+static void R128DRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
+ DRIContextType oldContextType, void *oldContext,
+ DRIContextType newContextType, void *newContext)
+{
+ if ((syncType==DRI_3D_SYNC) && (oldContextType==DRI_2D_CONTEXT) &&
+ (newContextType==DRI_2D_CONTEXT)) { /* Entering from Wakeup */
+ R128EnterServer(pScreen);
+ }
+ if ((syncType==DRI_2D_SYNC) && (oldContextType==DRI_NO_CONTEXT) &&
+ (newContextType==DRI_2D_CONTEXT)) { /* Exiting from Block Handler */
+ R128LeaveServer(pScreen);
+ }
+}
+
+/* Initialize the state of the back and depth buffers. */
+static void R128DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
+{
+ /* FIXME: This routine needs to have acceleration turned on */
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ R128InfoPtr pR128 = R128PTR(pScrn);
+ BoxPtr pbox;
+ int nbox;
+ int depth;
+
+ /* FIXME: Use accel when CCE 2D code is written */
+ if (pR128->CCE2D) return;
+
+ /* FIXME: This should be based on the __GLXvisualConfig info */
+ switch (pScrn->bitsPerPixel) {
+ case 8: depth = 0x000000ff; break;
+ case 16: depth = 0x0000ffff; break;
+ case 24: depth = 0x00ffffff; break;
+ case 32: depth = 0xffffffff; break;
+ default: depth = 0x00000000; break;
+ }
+
+ /* FIXME: Copy XAAPaintWindow() and use REGION_TRANSLATE() */
+ /* FIXME: Only initialize the back and depth buffers for contexts
+ that request them */
+
+ pbox = REGION_RECTS(prgn);
+ nbox = REGION_NUM_RECTS(prgn);
+
+ (*pR128->accel->SetupForSolidFill)(pScrn, 0, GXcopy, -1);
+ for (; nbox; nbox--, pbox++) {
+ (*pR128->accel->SubsequentSolidFillRect)(pScrn,
+ pbox->x1 + pR128->fbX,
+ pbox->y1 + pR128->fbY,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ (*pR128->accel->SubsequentSolidFillRect)(pScrn,
+ pbox->x1 + pR128->backX,
+ pbox->y1 + pR128->backY,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ }
+
+ (*pR128->accel->SetupForSolidFill)(pScrn, depth, GXcopy, -1);
+ for (; nbox; nbox--, pbox++)
+ (*pR128->accel->SubsequentSolidFillRect)(pScrn,
+ pbox->x1 + pR128->depthX,
+ pbox->y1 + pR128->depthY,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+
+ pR128->accel->NeedToSync = TRUE;
+}
+
+/* Copy the back and depth buffers when the X server moves a window. */
+static void R128DRIMoveBuffers(WindowPtr pWin, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc, CARD32 index)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ R128InfoPtr pR128 = R128PTR(pScrn);
+
+ /* FIXME: This routine needs to have acceleration turned on */
+ /* FIXME: Copy XAACopyWindow() and use REGION_TRANSLATE() */
+ /* FIXME: Only initialize the back and depth buffers for contexts
+ that request them */
+
+ /* FIXME: Use accel when CCE 2D code is written */
+ if (pR128->CCE2D) return;
+}
+
+/* Initialize the AGP state. Request memory for use in AGP space, and
+ initialize the Rage 128 registers to point to that memory. */
+static Bool R128DRIAgpInit(R128InfoPtr pR128, ScreenPtr pScreen)
+{
+ unsigned char *R128MMIO = pR128->MMIO;
+ unsigned long mode;
+ unsigned int vendor, device;
+ int ret;
+ unsigned long cntl;
+ int s, l;
+ int flags;
+
+ if (drmAgpAcquire(pR128->drmFD) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not available\n");
+ return FALSE;
+ }
+
+ /* Modify the mode if the default mode is
+ not appropriate for this particular
+ combination of graphics card and AGP
+ chipset. */
+
+ mode = drmAgpGetMode(pR128->drmFD); /* Default mode */
+ vendor = drmAgpVendorId(pR128->drmFD);
+ device = drmAgpDeviceId(pR128->drmFD);
+
+ mode &= ~R128_AGP_MODE_MASK;
+ switch (pR128->agpMode) {
+ case 2: mode |= R128_AGP_2X_MODE;
+ case 1: default: mode |= R128_AGP_1X_MODE;
+ }
+
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
+ mode, vendor, device,
+ pR128->PciInfo->vendor,
+ pR128->PciInfo->chipType);
+
+ if (drmAgpEnable(pR128->drmFD, mode) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n");
+ drmAgpRelease(pR128->drmFD);
+ return FALSE;
+ }
+
+ pR128->agpOffset = 0;
+
+ if ((ret = drmAgpAlloc(pR128->drmFD, pR128->agpSize*1024*1024, 0, NULL,
+ &pR128->agpMemHandle)) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret);
+ drmAgpRelease(pR128->drmFD);
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] %d kB allocated with handle 0x%08x\n",
+ pR128->agpSize*1024, pR128->agpMemHandle);
+
+ if (drmAgpBind(pR128->drmFD, pR128->agpMemHandle, pR128->agpOffset) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not bind\n");
+ drmAgpFree(pR128->drmFD, pR128->agpMemHandle);
+ drmAgpRelease(pR128->drmFD);
+ return FALSE;
+ }
+
+ /* Initialize the CCE ring buffer data */
+ pR128->ringStart = pR128->agpOffset;
+ pR128->ringMapSize = pR128->ringSize*1024*1024 + 4096;
+ pR128->ringSizeLog2QW = R128MinBits(pR128->ringSize*1024*1024/8) - 1;
+
+ pR128->ringReadOffset = pR128->ringStart + pR128->ringMapSize;
+ pR128->ringReadMapSize = 4096;
+
+ /* Reserve space for the vertex buffer */
+ pR128->vbStart = pR128->ringReadOffset + pR128->ringReadMapSize;
+ pR128->vbMapSize = pR128->vbSize*1024*1024;
+
+ /* Reserve space for the indirect buffer */
+ pR128->indStart = pR128->vbStart + pR128->vbMapSize;
+ pR128->indMapSize = pR128->indSize*1024*1024;
+
+ /* Reserve the rest for AGP textures */
+ pR128->agpTexStart = pR128->indStart + pR128->indMapSize;
+ s = (pR128->agpSize*1024*1024 - pR128->agpTexStart);
+ l = R128MinBits((s-1) / R128_NR_TEX_REGIONS);
+ if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY;
+ pR128->agpTexMapSize = (s >> l) << l;
+ pR128->log2AGPTexGran = l;
+
+ if (pR128->CCESecure) flags = DRM_READ_ONLY;
+ else flags = 0;
+
+ if (drmAddMap(pR128->drmFD, pR128->ringStart, pR128->ringMapSize,
+ DRM_AGP, flags, &pR128->ringHandle) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[agp] Could not add ring mapping\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] ring handle = 0x%08lx\n", pR128->ringHandle);
+
+ if (drmMap(pR128->drmFD, pR128->ringHandle, pR128->ringMapSize,
+ (drmAddressPtr)&pR128->ring) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not map ring\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] Ring mapped at 0x%08lx\n",
+ (unsigned long)pR128->ring);
+
+ if (drmAddMap(pR128->drmFD, pR128->ringReadOffset, pR128->ringReadMapSize,
+ DRM_AGP, flags, &pR128->ringReadPtrHandle) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[agp] Could not add ring read ptr mapping\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] ring read ptr handle = 0x%08lx\n",
+ pR128->ringReadPtrHandle);
+
+ if (drmMap(pR128->drmFD, pR128->ringReadPtrHandle, pR128->ringReadMapSize,
+ (drmAddressPtr)&pR128->ringReadPtr) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[agp] Could not map ring read ptr\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] Ring read ptr mapped at 0x%08lx\n",
+ (unsigned long)pR128->ringReadPtr);
+
+ if (drmAddMap(pR128->drmFD, pR128->vbStart, pR128->vbMapSize,
+ DRM_AGP, 0, &pR128->vbHandle) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[agp] Could not add vertex buffers mapping\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] vertex buffers handle = 0x%08lx\n", pR128->vbHandle);
+
+ if (drmMap(pR128->drmFD, pR128->vbHandle, pR128->vbMapSize,
+ (drmAddressPtr)&pR128->vb) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[agp] Could not map vertex buffers\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] Vertex buffers mapped at 0x%08lx\n",
+ (unsigned long)pR128->vb);
+
+ if (drmAddMap(pR128->drmFD, pR128->indStart, pR128->indMapSize,
+ DRM_AGP, flags, &pR128->indHandle) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[agp] Could not add indirect buffers mapping\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] indirect buffers handle = 0x%08lx\n", pR128->indHandle);
+
+ if (drmMap(pR128->drmFD, pR128->indHandle, pR128->indMapSize,
+ (drmAddressPtr)&pR128->ind) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[agp] Could not map indirect buffers\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] Indirect buffers mapped at 0x%08lx\n",
+ (unsigned long)pR128->ind);
+
+ if (drmAddMap(pR128->drmFD, pR128->agpTexStart, pR128->agpTexMapSize,
+ DRM_AGP, 0, &pR128->agpTexHandle) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[agp] Could not add AGP texture map mapping\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] AGP texture map handle = 0x%08lx\n",
+ pR128->agpTexHandle);
+
+ if (drmMap(pR128->drmFD, pR128->agpTexHandle, pR128->agpTexMapSize,
+ (drmAddressPtr)&pR128->agpTex) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[agp] Could not map AGP texture map\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[agp] AGP Texture map mapped at 0x%08lx\n",
+ (unsigned long)pR128->agpTex);
+
+ /* Initialize Rage 128's AGP registers */
+ cntl = INREG(R128_AGP_CNTL);
+ cntl &= ~R128_AGP_APER_SIZE_MASK;
+ switch (pR128->agpSize) {
+ case 256: cntl |= R128_AGP_APER_SIZE_256MB; break;
+ case 128: cntl |= R128_AGP_APER_SIZE_128MB; break;
+ case 64: cntl |= R128_AGP_APER_SIZE_64MB; break;
+ case 32: cntl |= R128_AGP_APER_SIZE_32MB; break;
+ case 16: cntl |= R128_AGP_APER_SIZE_16MB; break;
+ case 8: cntl |= R128_AGP_APER_SIZE_8MB; break;
+ case 4: cntl |= R128_AGP_APER_SIZE_4MB; break;
+ default:
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[agp] Illegal aperture size %d kB\n",
+ pR128->agpSize*1024);
+ return FALSE;
+ }
+ OUTREG(R128_AGP_BASE, pR128->ringHandle); /* Ring buf is at AGP offset 0 */
+ OUTREG(R128_AGP_CNTL, cntl);
+
+ return TRUE;
+}
+
+/* Add a map for the MMIO registers that will be accessed by any
+ DRI-based clients. */
+static Bool R128DRIMapInit(R128InfoPtr pR128, ScreenPtr pScreen)
+{
+ int flags;
+
+ if (pR128->CCESecure) flags = DRM_READ_ONLY;
+ else flags = 0;
+
+ /* Map registers */
+ pR128->registerSize = R128_MMIOSIZE;
+ if (drmAddMap(pR128->drmFD, pR128->MMIOAddr, pR128->registerSize,
+ DRM_REGISTERS, flags, &pR128->registerHandle) < 0) {
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] register handle = 0x%08lx\n", pR128->registerHandle);
+
+ return TRUE;
+}
+
+/* Initialize the ring buffer state for use in the X server and any
+ DRI-based clients. */
+static void R128DRICCEInitRingBuffer(ScrnInfoPtr pScrn)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+ unsigned long addr;
+
+ /* FIXME: When we use the CCE for the X server, we should move this
+ function (and the support functions above) to r128_accel.c */
+
+ /* The manual (p. 2) says this address is
+ in "VM space". This means it's an
+ offset from the start of AGP space. */
+ OUTREG(R128_PM4_BUFFER_OFFSET, info->ringStart | 0x02000000);
+
+ OUTREG(R128_PM4_BUFFER_DL_WPTR, 0);
+ OUTREG(R128_PM4_BUFFER_DL_RPTR, 0);
+
+ /* DL_RPTR_ADDR is a physical address.
+ This should be in the SAREA. */
+ *(volatile long unsigned *)(info->ringReadPtr) = 0;
+ OUTREG(R128_PM4_BUFFER_DL_RPTR_ADDR, (info->ringReadPtrHandle));
+
+ /* Set watermark control */
+ OUTREG(R128_PM4_BUFFER_WM_CNTL,
+ ((R128_WATERMARK_L/4) << R128_WMA_SHIFT)
+ | ((R128_WATERMARK_M/4) << R128_WMB_SHIFT)
+ | ((R128_WATERMARK_N/4) << R128_WMC_SHIFT)
+ | ((R128_WATERMARK_K/64) << R128_WB_WM_SHIFT));
+
+ addr = INREG(R128_PM4_BUFFER_ADDR); /* Force read. Why? Because it's
+ in the examples... */
+
+#if 0
+ R128CCEWaitForIdle(pScrn);
+#endif
+
+ /* Turn on bus mastering */
+ info->BusCntl &= ~R128_BUS_MASTER_DIS;
+ OUTREGP(R128_BUS_CNTL, 0, ~R128_BUS_MASTER_DIS);
+}
+
+/* Initialize the kernel data structures. */
+static int R128DRIKernelInit(R128InfoPtr pR128, ScreenPtr pScreen)
+{
+ drmR128Init drmInfo;
+
+ drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec);
+ drmInfo.is_pci = pR128->IsPCI;
+ drmInfo.cce_mode = pR128->CCEMode;
+ drmInfo.cce_fifo_size = pR128->CCEFifoSize;
+ drmInfo.cce_secure = pR128->CCESecure;
+ drmInfo.ring_size = pR128->ringSize*1024*1024;
+ drmInfo.usec_timeout = pR128->CCEusecTimeout;
+
+ drmInfo.fb_offset = pR128->LinearAddr;
+ drmInfo.agp_ring_offset = pR128->ringHandle;
+ drmInfo.agp_read_ptr_offset = pR128->ringReadPtrHandle;
+ drmInfo.agp_vertbufs_offset = pR128->vbHandle;
+ drmInfo.agp_indbufs_offset = pR128->indHandle;
+ drmInfo.agp_textures_offset = pR128->agpTexHandle;
+ drmInfo.mmio_offset = pR128->registerHandle;
+
+ if (drmR128InitCCE(pR128->drmFD, &drmInfo) < 0) return FALSE;
+
+ return TRUE;
+}
+
+/* Add a map for the vertex buffers that will be accessed by any
+ DRI-based clients. */
+static Bool R128DRIBufInit(R128InfoPtr pR128, ScreenPtr pScreen)
+{
+ /* Initialize vertex buffers */
+ if ((pR128->vbNumBufs = drmAddBufs(pR128->drmFD,
+ pR128->vbMapSize / pR128->vbBufSize,
+ pR128->vbBufSize,
+ DRM_AGP_BUFFER,
+ pR128->vbStart)) <= 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] Could not create vertex buffers list\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Added %d %d byte vertex buffers\n",
+ pR128->vbNumBufs, pR128->vbBufSize);
+
+ if (drmMarkBufs(pR128->drmFD, 0.133333, 0.266666)) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] Failed to mark vertex buffers list\n");
+ return FALSE;
+ }
+
+ if (!(pR128->vbBufs = drmMapBufs(pR128->drmFD))) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] Failed to map vertex buffers list\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Mapped %d vertex buffers\n",
+ pR128->vbBufs->count);
+
+ return TRUE;
+}
+
+/* Load the microcode for the CCE */
+static void R128DRILoadMicrocode(ScrnInfoPtr pScrn)
+{
+ unsigned char *R128MMIO = R128PTR(pScrn)->MMIO;
+ int i;
+ unsigned long R128Microcode[] = {
+ /* CCE microcode (from ATI) */
+ 0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0, 1617039951,
+ 0, 774592877, 0, 1987540286, 0, 2307490946U, 0, 599558925, 0, 589505315, 0,
+ 596487092, 0, 589505315, 1, 11544576, 1, 206848, 1, 311296, 1, 198656, 2,
+ 912273422, 11, 262144, 0, 0, 1, 33559837, 1, 7438, 1, 14809, 1, 6615, 12,
+ 28, 1, 6614, 12, 28, 2, 23, 11, 18874368, 0, 16790922, 1, 409600, 9, 30, 1,
+ 147854772, 16, 420483072, 3, 8192, 0, 10240, 1, 198656, 1, 15630, 1, 51200,
+ 10, 34858, 9, 42, 1, 33559823, 2, 10276, 1, 15717, 1, 15718, 2, 43, 1,
+ 15936948, 1, 570480831, 1, 14715071, 12, 322123831, 1, 33953125, 12, 55, 1,
+ 33559908, 1, 15718, 2, 46, 4, 2099258, 1, 526336, 1, 442623, 4, 4194365, 1,
+ 509952, 1, 459007, 3, 0, 12, 92, 2, 46, 12, 176, 1, 15734, 1, 206848, 1,
+ 18432, 1, 133120, 1, 100670734, 1, 149504, 1, 165888, 1, 15975928, 1,
+ 1048576, 6, 3145806, 1, 15715, 16, 2150645232U, 2, 268449859, 2, 10307, 12,
+ 176, 1, 15734, 1, 15735, 1, 15630, 1, 15631, 1, 5253120, 6, 3145810, 16,
+ 2150645232U, 1, 15864, 2, 82, 1, 343310, 1, 1064207, 2, 3145813, 1, 15728,
+ 1, 7817, 1, 15729, 3, 15730, 12, 92, 2, 98, 1, 16168, 1, 16167, 1, 16002,
+ 1, 16008, 1, 15974, 1, 15975, 1, 15990, 1, 15976, 1, 15977, 1, 15980, 0,
+ 15981, 1, 10240, 1, 5253120, 1, 15720, 1, 198656, 6, 110, 1, 180224, 1,
+ 103824738, 2, 112, 2, 3145839, 0, 536885440, 1, 114880, 14, 125, 12,
+ 206975, 1, 33559995, 12, 198784, 0, 33570236, 1, 15803, 0, 15804, 3,
+ 294912, 1, 294912, 3, 442370, 1, 11544576, 0, 811612160, 1, 12593152, 1,
+ 11536384, 1, 14024704, 7, 310382726, 0, 10240, 1, 14796, 1, 14797, 1,
+ 14793, 1, 14794, 0, 14795, 1, 268679168, 1, 9437184, 1, 268449792, 1,
+ 198656, 1, 9452827, 1, 1075854602, 1, 1075854603, 1, 557056, 1, 114880, 14,
+ 159, 12, 198784, 1, 1109409213, 12, 198783, 1, 1107312059, 12, 198784, 1,
+ 1109409212, 2, 162, 1, 1075854781, 1, 1073757627, 1, 1075854780, 1, 540672,
+ 1, 10485760, 6, 3145894, 16, 274741248, 9, 168, 3, 4194304, 3, 4209949, 0,
+ 0, 0, 256, 14, 174, 1, 114857, 1, 33560007, 12, 176, 0, 10240, 1, 114858,
+ 1, 33560018, 1, 114857, 3, 33560007, 1, 16008, 1, 114874, 1, 33560360, 1,
+ 114875, 1, 33560154, 0, 15963, 0, 256, 0, 4096, 1, 409611, 9, 188, 0,
+ 10240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0
+ };
+
+ R128WaitForIdle(pScrn);
+
+ OUTREG(R128_PM4_MICROCODE_ADDR, 0);
+ for (i = 0; i < 256; i += 1) {
+ OUTREG(R128_PM4_MICROCODE_DATAH, R128Microcode[i*2]);
+ OUTREG(R128_PM4_MICROCODE_DATAL, R128Microcode[i*2 + 1]);
+ }
+}
+
+/* Initialize the CCE state, and start the CCE (if used by the X server) */
+static void R128DRICCEInit(ScrnInfoPtr pScrn)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+
+ /* CCEMode is initialized in r128_driver.c */
+ switch (info->CCEMode) {
+ case R128_PM4_NONPM4: info->CCEFifoSize = 0; break;
+ case R128_PM4_192PIO: info->CCEFifoSize = 192; break;
+ case R128_PM4_192BM: info->CCEFifoSize = 192; break;
+ case R128_PM4_128PIO_64INDBM: info->CCEFifoSize = 128; break;
+ case R128_PM4_128BM_64INDBM: info->CCEFifoSize = 128; break;
+ case R128_PM4_64PIO_128INDBM: info->CCEFifoSize = 64; break;
+ case R128_PM4_64BM_128INDBM: info->CCEFifoSize = 64; break;
+ case R128_PM4_64PIO_64VCBM_64INDBM: info->CCEFifoSize = 64; break;
+ case R128_PM4_64BM_64VCBM_64INDBM: info->CCEFifoSize = 64; break;
+ case R128_PM4_64PIO_64VCPIO_64INDPIO: info->CCEFifoSize = 64; break;
+ }
+
+ if (info->CCE2D) {
+ /* Make sure the CCE is on for the X server */
+ R128CCEStart(pScrn);
+ } else {
+ /* Make sure the CCE is off for the X server */
+ OUTREG(R128_PM4_MICRO_CNTL, 0);
+ OUTREG(R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4);
+ }
+}
+
+/* Initialize the screen-specific data structures for the DRI and the
+ Rage 128. This is the main entry point to the device-specific
+ initialization code. It calls device-independent DRI functions to
+ create the DRI data structures and initialize the DRI state. */
+Bool R128DRIScreenInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ R128InfoPtr pR128 = R128PTR(pScrn);
+ DRIInfoPtr pDRIInfo;
+ R128DRIPtr pR128DRI;
+
+ switch (pR128->pixel_code) {
+ case 8:
+ /* These modes are not supported (yet). */
+ case 15:
+ case 24:
+ return FALSE;
+
+ /* Only 16 and 32 color depths are supports currently. */
+ case 16:
+ case 32:
+ break;
+ }
+
+ /* Create the DRI data structure, and fill it in before calling the
+ DRIScreenInit(). */
+ if (!(pDRIInfo = DRICreateInfoRec())) return FALSE;
+
+ pR128->pDRIInfo = pDRIInfo;
+ pDRIInfo->drmDriverName = R128_NAME;
+ pDRIInfo->clientDriverName = R128_NAME;
+ pDRIInfo->busIdString = xalloc(64);
+ sprintf(pDRIInfo->busIdString,
+ "PCI:%d:%d:%d",
+ pR128->PciInfo->bus,
+ pR128->PciInfo->device,
+ pR128->PciInfo->func);
+ pDRIInfo->ddxDriverMajorVersion = R128_VERSION_MAJOR;
+ pDRIInfo->ddxDriverMinorVersion = R128_VERSION_MINOR;
+ pDRIInfo->ddxDriverPatchVersion = R128_VERSION_PATCH;
+ pDRIInfo->frameBufferPhysicalAddress = pR128->LinearAddr;
+ pDRIInfo->frameBufferSize = pR128->FbMapSize;
+ pDRIInfo->frameBufferStride = (pScrn->displayWidth
+ * pR128->pixel_bytes);
+ pDRIInfo->ddxDrawableTableEntry = R128_MAX_DRAWABLES;
+ pDRIInfo->maxDrawableTableEntry = (SAREA_MAX_DRAWABLES
+ < R128_MAX_DRAWABLES
+ ? SAREA_MAX_DRAWABLES
+ : R128_MAX_DRAWABLES);
+
+#ifdef NOT_DONE
+ /* FIXME: Need to extend DRI protocol to pass this size back to
+ * client for SAREA mapping that includes a device private record
+ */
+ pDRIInfo->SAREASize =
+ ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */
+ /* + shared memory device private rec */
+#else
+ /* For now the mapping works by using a fixed size defined
+ * in the SAREA header
+ */
+ if (sizeof(XF86DRISAREARec)+sizeof(R128SAREAPriv)>SAREA_MAX) {
+ ErrorF("Data does not fit in SAREA\n");
+ return FALSE;
+ }
+ pDRIInfo->SAREASize = SAREA_MAX;
+#endif
+
+ if (!(pR128DRI = (R128DRIPtr)xnfcalloc(sizeof(R128DRIRec),1))) {
+ DRIDestroyInfoRec(pR128->pDRIInfo);
+ pR128->pDRIInfo = NULL;
+ return FALSE;
+ }
+ pDRIInfo->devPrivate = pR128DRI;
+ pDRIInfo->devPrivateSize = sizeof(R128DRIRec);
+ pDRIInfo->contextSize = sizeof(R128DRIContextRec);
+
+ pDRIInfo->CreateContext = R128CreateContext;
+ pDRIInfo->DestroyContext = R128DestroyContext;
+ pDRIInfo->SwapContext = R128DRISwapContext;
+ pDRIInfo->InitBuffers = R128DRIInitBuffers;
+ pDRIInfo->MoveBuffers = R128DRIMoveBuffers;
+ pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
+
+ if (!DRIScreenInit(pScreen, pDRIInfo, &pR128->drmFD)) {
+ xfree(pDRIInfo->devPrivate);
+ pDRIInfo->devPrivate = NULL;
+ DRIDestroyInfoRec(pDRIInfo);
+ pDRIInfo = NULL;
+ return FALSE;
+ }
+
+ /* Initialize AGP */
+ if (!pR128->IsPCI && !R128DRIAgpInit(pR128, pScreen)) {
+ R128DRICloseScreen(pScreen);
+ return FALSE;
+ }
+
+ /* DRIScreenInit doesn't add all the
+ common mappings. Add additional
+ mappings here. */
+ if (!R128DRIMapInit(pR128, pScreen)) {
+ R128DRICloseScreen(pScreen);
+ return FALSE;
+ }
+
+ /* Initialize the ring buffer */
+ if (!pR128->IsPCI) R128DRICCEInitRingBuffer(pScrn);
+
+ /* Initialize the kernel data structures */
+ if (!R128DRIKernelInit(pR128, pScreen)) {
+ R128DRICloseScreen(pScreen);
+ return FALSE;
+ }
+
+ /* Initialize vertex buffers list */
+ if (!pR128->IsPCI && !R128DRIBufInit(pR128, pScreen)) {
+ R128DRICloseScreen(pScreen);
+ return FALSE;
+ }
+
+ /* FIXME: When are these mappings unmapped? */
+
+ if (!R128InitVisualConfigs(pScreen)) {
+ R128DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Visual configs initialized\n");
+
+ /* Load the CCE Microcode */
+ R128DRILoadMicrocode(pScrn);
+
+ /* Reset the Graphics Engine */
+ R128EngineReset(pScrn);
+
+ return TRUE;
+}
+
+/* Finish initializing the device-dependent DRI state, and call
+ DRIFinishScreenInit() to complete the device-independent DRI
+ initialization. */
+Bool R128DRIFinishScreenInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ R128InfoPtr pR128 = R128PTR(pScrn);
+ R128SAREAPrivPtr pSAREAPriv;
+ R128DRIPtr pR128DRI;
+
+ /* Init and start the CCE */
+ R128DRICCEInit(pScrn);
+
+ pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScreen);
+ memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
+
+ pR128->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
+ /* pR128->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP; */
+
+ pR128DRI = (R128DRIPtr)pR128->pDRIInfo->devPrivate;
+ pR128DRI->registerHandle = pR128->registerHandle;
+ pR128DRI->registerSize = pR128->registerSize;
+
+ pR128DRI->ringHandle = pR128->ringHandle;
+ pR128DRI->ringMapSize = pR128->ringMapSize;
+ pR128DRI->ringSize = pR128->ringSize*1024*1024;
+
+ pR128DRI->ringReadPtrHandle = pR128->ringReadPtrHandle;
+ pR128DRI->ringReadMapSize = pR128->ringReadMapSize;
+
+ pR128DRI->vbHandle = pR128->vbHandle;
+ pR128DRI->vbMapSize = pR128->vbMapSize;
+ pR128DRI->vbOffset = pR128->vbStart;
+ pR128DRI->vbBufSize = pR128->vbBufSize;
+
+ pR128DRI->indHandle = pR128->indHandle;
+ pR128DRI->indMapSize = pR128->indMapSize;
+
+ pR128DRI->agpTexHandle = pR128->agpTexHandle;
+ pR128DRI->agpTexMapSize = pR128->agpTexMapSize;
+ pR128DRI->log2AGPTexGran = pR128->log2AGPTexGran;
+ pR128DRI->agpTexOffset = pR128->agpTexStart;
+
+ pR128DRI->deviceID = pR128->Chipset;
+ pR128DRI->width = pScrn->virtualX;
+ pR128DRI->height = pScrn->virtualY;
+ pR128DRI->depth = pScrn->depth;
+ pR128DRI->bpp = pScrn->bitsPerPixel;
+
+ pR128DRI->fbX = pR128->fbX;
+ pR128DRI->fbY = pR128->fbY;
+ pR128DRI->backX = pR128->backX;
+ pR128DRI->backY = pR128->backY;
+ pR128DRI->depthX = pR128->depthX;
+ pR128DRI->depthY = pR128->depthY;
+ pR128DRI->textureX = pR128->textureX;
+ pR128DRI->textureY = pR128->textureY;
+ pR128DRI->textureSize = pR128->textureSize;
+ pR128DRI->log2TexGran = pR128->log2TexGran;
+
+ pR128DRI->IsPCI = pR128->IsPCI;
+
+ pR128DRI->CCEMode = pR128->CCEMode;
+ pR128DRI->CCEFifoSize = pR128->CCEFifoSize;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "0x%08lx %d\n",
+ pR128DRI->registerHandle, pR128DRI->registerSize);
+ return DRIFinishScreenInit(pScreen);
+}
+
+/* The screen is being closed, so clean up any state and free any
+ resources used by the DRI. */
+void R128DRICloseScreen(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ R128InfoPtr pR128 = R128PTR(pScrn);
+
+ /* Stop the CCE if it is still in use */
+ if (pR128->CCE2D) R128CCEStop(pScrn);
+
+ /* De-allocate vertex buffers */
+ if (pR128->vbBufs) {
+ drmUnmapBufs(pR128->vbBufs);
+ pR128->vbBufs = NULL;
+ }
+
+ /* De-allocate all kernel resources */
+ drmR128CleanupCCE(pR128->drmFD);
+
+ /* De-allocate all AGP resources */
+ if (pR128->agpTex) {
+ drmUnmap(pR128->agpTex, pR128->agpTexMapSize);
+ pR128->agpTex = NULL;
+ }
+ if (pR128->ind) {
+ drmUnmap(pR128->ind, pR128->indMapSize);
+ pR128->ind = NULL;
+ }
+ if (pR128->vb) {
+ drmUnmap(pR128->vb, pR128->vbMapSize);
+ pR128->vb = NULL;
+ }
+ if (pR128->ringReadPtr) {
+ drmUnmap(pR128->ringReadPtr, pR128->ringReadMapSize);
+ pR128->ringReadPtr = NULL;
+ }
+ if (pR128->ring) {
+ drmUnmap(pR128->ring, pR128->ringMapSize);
+ pR128->ring = NULL;
+ }
+ if (pR128->agpMemHandle) {
+ drmAgpUnbind(pR128->drmFD, pR128->agpMemHandle);
+ drmAgpFree(pR128->drmFD, pR128->agpMemHandle);
+ pR128->agpMemHandle = 0;
+ drmAgpRelease(pR128->drmFD);
+ }
+
+ /* De-allocate all DRI resources */
+ DRICloseScreen(pScreen);
+
+ /* De-allocate all DRI data structures */
+ if (pR128->pDRIInfo) {
+ if (pR128->pDRIInfo->devPrivate) {
+ xfree(pR128->pDRIInfo->devPrivate);
+ pR128->pDRIInfo->devPrivate = NULL;
+ }
+ DRIDestroyInfoRec(pR128->pDRIInfo);
+ pR128->pDRIInfo = NULL;
+ }
+ if (pR128->pVisualConfigs) {
+ xfree(pR128->pVisualConfigs);
+ pR128->pVisualConfigs = NULL;
+ }
+ if (pR128->pVisualConfigsPriv) {
+ xfree(pR128->pVisualConfigsPriv);
+ pR128->pVisualConfigsPriv = NULL;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.h
new file mode 100644
index 000000000..533aadb2f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.h
@@ -0,0 +1,116 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Rickard E. Faith <faith@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_DRI_
+#define _R128_DRI_
+
+#include <xf86drm.h>
+
+/* DRI Driver defaults */
+#define R128_DEFAULT_CCE_PIO_MODE R128_PM4_64PIO_64VCBM_64INDBM
+#define R128_DEFAULT_CCE_BM_MODE R128_PM4_64BM_64VCBM_64INDBM
+#define R128_DEFAULT_AGP_MODE 2
+#define R128_DEFAULT_AGP_SIZE 8 /* MB (must be a power of 2 and > 4MB) */
+#define R128_DEFAULT_RING_SIZE 1 /* MB (must be page aligned) */
+#define R128_DEFAULT_VB_SIZE 1 /* MB (must be page aligned) */
+#define R128_DEFAULT_IND_SIZE 1 /* MB (must be page aligned) */
+#define R128_DEFAULT_AGP_TEX_SIZE 1 /* MB (must be page aligned) */
+
+#define R128_DEFAULT_VB_BUF_SIZE 16384 /* bytes */
+#define R128_DEFAULT_CCE_TIMEOUT 10000 /* usecs */
+
+#define R128_AGP_MAX_MODE 2
+
+#define R128CCE_USE_RING_BUFFER(m) \
+(((m) == R128_PM4_192BM) || \
+ ((m) == R128_PM4_128BM_64INDBM) || \
+ ((m) == R128_PM4_64BM_128INDBM) || \
+ ((m) == R128_PM4_64BM_64VCBM_64INDBM))
+
+typedef struct {
+ /* MMIO register data */
+ drmHandle registerHandle;
+ drmSize registerSize;
+
+ /* CCE ring buffer data */
+ drmHandle ringHandle;
+ drmSize ringMapSize;
+ int ringSize;
+
+ /* CCE ring read pointer data */
+ drmHandle ringReadPtrHandle;
+ drmSize ringReadMapSize;
+
+ /* CCE vertex buffer data */
+ drmHandle vbHandle;
+ drmSize vbMapSize;
+ int vbOffset;
+ int vbBufSize;
+
+ /* CCE indirect buffer data */
+ drmHandle indHandle;
+ drmSize indMapSize;
+
+ /* CCE AGP Texture data */
+ drmHandle agpTexHandle;
+ drmSize agpTexMapSize;
+ int log2AGPTexGran;
+ int agpTexOffset;
+
+ /* DRI screen private data */
+ int deviceID; /* PCI device ID */
+ int width; /* Width in pixels of display */
+ int height; /* Height in scanlines of display */
+ int depth; /* Depth of display (8, 15, 16, 24) */
+ int bpp; /* Bit depth of display (8, 16, 24, 32) */
+
+ int fbX; /* Start of frame buffer */
+ int fbY;
+ int backX; /* Start of shared back buffer */
+ int backY;
+ int depthX; /* Start of shared depth buffer */
+ int depthY;
+ int textureX; /* Start of texture data in frame buffer */
+ int textureY;
+ int textureSize;
+ int log2TexGran;
+
+ int IsPCI; /* Current card is a PCI card */
+
+ int CCEMode; /* CCE mode that server/clients use */
+ int CCEFifoSize; /* Size of the CCE command FIFO */
+} R128DRIRec, *R128DRIPtr;
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dripriv.h
new file mode 100644
index 000000000..acec5e269
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dripriv.h
@@ -0,0 +1,54 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Rickard E. Faith <faith@precisioninsight.com>
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_DRIPRIV_H_
+#define _R128_DRIPRIV_H_
+
+#define R128_MAX_DRAWABLES 256
+
+extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
+ void **configprivs);
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} R128ConfigPrivRec, *R128ConfigPrivPtr;
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} R128DRIContextRec, *R128DRIContextPtr;
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c
index b5da4cb6e..f30d86aa8 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c
@@ -1,8 +1,8 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c,v 1.26 2000/03/06 23:17:44 martin Exp $ */
/**************************************************************************
-Copyright 1999 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -107,6 +107,19 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
/* VESA support */
#include "vbe.h"
+ /* DRI support */
+#ifdef XF86DRI
+#include "GL/glxint.h"
+#include "xf86drm.h"
+#include "sarea.h"
+#define _XF86DRI_SERVER_
+#include "xf86dri.h"
+#include "dri.h"
+#include "r128_dri.h"
+#include "r128_dripriv.h"
+#include "r128_sarea.h"
+#endif
+
/* Driver data structures */
#include "r128.h"
#include "r128_reg.h"
@@ -176,17 +189,41 @@ typedef enum {
OPTION_HW_CURSOR,
OPTION_DAC_6BIT,
OPTION_DAC_8BIT,
+#ifdef XF86DRI
+ OPTION_IS_PCI,
+ OPTION_CCE_PIO,
+ OPTION_NO_SECURITY,
+ OPTION_USEC_TIMEOUT,
+ OPTION_AGP_MODE,
+ OPTION_AGP_SIZE,
+ OPTION_RING_SIZE,
+ OPTION_VERT_SIZE,
+ OPTION_VBUF_SIZE,
+ OPTION_USE_CCE_2D,
+#endif
OPTION_FBDEV
} R128Opts;
static OptionInfoRec R128Options[] = {
- { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, TRUE },
- { OPTION_DAC_6BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_DAC_8BIT, "Dac8Bit", OPTV_BOOLEAN, {0}, TRUE },
- { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE },
- { -1, NULL, OPTV_NONE, {0}, FALSE }
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, TRUE },
+ { OPTION_DAC_6BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_DAC_8BIT, "Dac8Bit", OPTV_BOOLEAN, {0}, TRUE },
+#ifdef XF86DRI
+ { OPTION_IS_PCI, "ForcePCIMode", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_CCE_PIO, "CCEPIOMode", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NO_SECURITY, "CCENoSecurity", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_USEC_TIMEOUT, "CCEusecTimeout", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_AGP_MODE, "AGPMode", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_RING_SIZE, "RingSize", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_VERT_SIZE, "VBListSize", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_VBUF_SIZE, "VBSize", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_USE_CCE_2D, "UseCCEfor2D", OPTV_BOOLEAN, {0}, FALSE },
+#endif
+ { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
};
R128RAMRec R128RAM[] = { /* Memory Specifications
@@ -299,6 +336,38 @@ static const char *ramdacSymbols[] = {
NULL
};
+#ifdef XF86DRI
+static const char *drmSymbols[] = {
+ "drmAddBufs",
+ "drmAddMap",
+ "drmAvailable",
+ "drmCtlAddCommand",
+ "drmCtlInstHandler",
+ "drmGetInterruptFromBusID",
+ "drmMapBufs",
+ "drmMarkBufs",
+ "drmUnmapBufs",
+ NULL
+};
+
+static const char *driSymbols[] = {
+ "DRIGetDrawableIndex",
+ "DRIFinishScreenInit",
+ "DRIDestroyInfoRec",
+ "DRICloseScreen",
+ "DRIDestroyInfoRec",
+ "DRIScreenInit",
+ "DRIDestroyInfoRec",
+ "DRICreateInfoRec",
+ "DRILock",
+ "DRIUnlock",
+ "DRIGetSAREAPrivate",
+ "DRIGetContext",
+ "GlxSetVisualConfigs",
+ NULL
+};
+#endif
+
static MODULESETUPPROTO(R128Setup);
static XF86ModuleVersionInfo R128VersRec =
@@ -347,6 +416,10 @@ static pointer R128Setup(pointer module, pointer opts, int *errmaj,
xaaSymbols,
xf8_32bppSymbols,
ramdacSymbols,
+#ifdef XF86DRI
+ drmSymbols,
+ driSymbols,
+#endif
fbdevHWSymbols,
vbeSymbols,
0 /* ddcsymbols */,
@@ -518,7 +591,7 @@ static void R128Unblank(ScrnInfoPtr pScrn)
}
/* Compute log base 2 of val. */
-static int R128MinBits(int val)
+int R128MinBits(int val)
{
int bits;
@@ -779,6 +852,7 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
int offset = 0; /* RAM Type */
MessageType from;
unsigned char *R128MMIO;
+
/* Chipset */
from = X_PROBED;
if (dev->chipset && *dev->chipset) {
@@ -876,7 +950,7 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
switch (info->MemCntl & 0x3) {
case 0: /* SDR SGRAM 1:1 */
switch (info->Chipset) {
- case PCI_CHIP_RAGE128RE:
+ case PCI_CHIP_RAGE128RE:
case PCI_CHIP_RAGE128RF: offset = 0; break; /* 128-bit SDR SGRAM 1:1 */
case PCI_CHIP_RAGE128RK:
case PCI_CHIP_RAGE128RL:
@@ -895,12 +969,28 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
pScrn->videoRam);
from = X_CONFIG;
pScrn->videoRam = dev->videoRam;
- }
+ }
pScrn->videoRam &= ~1023;
info->FbMapSize = pScrn->videoRam * 1024;
xf86DrvMsg(pScrn->scrnIndex, from,
"VideoRAM: %d kByte (%s)\n", pScrn->videoRam, info->ram->name);
+#ifdef XF86DRI
+ /* AGP/PCI */
+ if (xf86ReturnOptValBool(R128Options, OPTION_IS_PCI, FALSE)) {
+ info->IsPCI = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into PCI-only mode\n");
+ } else {
+ switch (info->Chipset) {
+ case PCI_CHIP_RAGE128RE:
+ case PCI_CHIP_RAGE128RK: info->IsPCI = TRUE; break;
+ case PCI_CHIP_RAGE128RF:
+ case PCI_CHIP_RAGE128RL:
+ case PCI_CHIP_RAGE128PF:
+ default: info->IsPCI = FALSE; break;
+ }
+ }
+#endif
return TRUE;
}
@@ -1053,6 +1143,143 @@ static Bool R128PreInitInt10(ScrnInfoPtr pScrn)
return TRUE;
}
+#ifdef XF86DRI
+static Bool R128PreInitDRI(ScrnInfoPtr pScrn)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+
+ if (info->IsPCI) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "CCE in PIO mode\n");
+ info->CCEMode = R128_DEFAULT_CCE_PIO_MODE;
+ } else if (xf86ReturnOptValBool(R128Options, OPTION_CCE_PIO, FALSE)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "CCE in PIO mode\n");
+ info->CCEMode = R128_DEFAULT_CCE_PIO_MODE;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "CCE in BM mode\n");
+ info->CCEMode = R128_DEFAULT_CCE_BM_MODE;
+ }
+
+ if (xf86ReturnOptValBool(R128Options, OPTION_USE_CCE_2D, FALSE)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using CCE for 2D\n");
+ info->CCE2D = TRUE;
+ } else {
+ info->CCE2D = FALSE;
+ }
+
+ if (xf86ReturnOptValBool(R128Options, OPTION_NO_SECURITY, FALSE)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "WARNING!!! CCE Security checks disabled!!! **********\n");
+ info->CCESecure = FALSE;
+ } else {
+ info->CCESecure = TRUE;
+ }
+
+ info->agpMode = R128_DEFAULT_AGP_MODE;
+ info->agpSize = R128_DEFAULT_AGP_SIZE;
+ info->ringSize = R128_DEFAULT_RING_SIZE;
+ info->vbSize = R128_DEFAULT_VB_SIZE;
+ info->indSize = R128_DEFAULT_IND_SIZE;
+ info->agpTexSize = R128_DEFAULT_AGP_TEX_SIZE;
+
+ info->vbBufSize = R128_DEFAULT_VB_BUF_SIZE;
+
+ info->CCEusecTimeout = R128_DEFAULT_CCE_TIMEOUT;
+
+ if (!info->IsPCI) {
+ if (xf86GetOptValInteger(R128Options,
+ OPTION_AGP_MODE, &(info->agpMode))) {
+ if (info->agpMode < 1 || info->agpMode > R128_AGP_MAX_MODE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Illegal AGP Mode: %d\n", info->agpMode);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using AGP %dx mode\n", info->agpMode);
+ }
+
+ if (xf86GetOptValInteger(R128Options,
+ OPTION_AGP_SIZE, (int *)&(info->agpSize))) {
+ switch (info->agpSize) {
+ case 4:
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+ case 128:
+ case 256:
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Illegal AGP size: %d MB\n", info->agpSize);
+ return FALSE;
+ }
+ }
+
+ if (xf86GetOptValInteger(R128Options,
+ OPTION_RING_SIZE, &(info->ringSize))) {
+ if (info->ringSize < 1 || info->ringSize >= info->agpSize) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Illegal ring buffer size: %d MB\n",
+ info->ringSize);
+ return FALSE;
+ }
+ }
+
+ if (xf86GetOptValInteger(R128Options,
+ OPTION_VERT_SIZE, &(info->vbSize))) {
+ if (info->vbSize < 1 || info->vbSize >= info->agpSize) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Illegal vertex buffers list size: %d MB\n",
+ info->vbSize);
+ return FALSE;
+ }
+ }
+
+ if (xf86GetOptValInteger(R128Options,
+ OPTION_VBUF_SIZE, &(info->vbBufSize))) {
+ int numBufs = info->vbSize*1024*1024/info->vbBufSize;
+ if (numBufs < 2 || numBufs > 512) { /* FIXME: 512 is arbitrary */
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Illegal individual vertex buffer size: %d bytes\n",
+ info->vbBufSize);
+ return FALSE;
+ }
+ }
+
+ if (info->ringSize + info->vbSize + info->indSize + info->agpTexSize >
+ info->agpSize) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Buffers are too big for requested AGP space\n");
+ return FALSE;
+ }
+
+ info->agpTexSize = info->agpSize - (info->ringSize +
+ info->vbSize +
+ info->indSize);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using %d MB AGP aperture\n", info->agpSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using %d MB for the ring buffer\n", info->ringSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using %d MB for vertex buffers\n", info->vbSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using %d MB for indirect buffers\n", info->indSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using %d MB for AGP textures\n", info->agpTexSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using %d byte vertex buffers\n", info->vbBufSize);
+ }
+
+ if (xf86GetOptValInteger(R128Options, OPTION_USEC_TIMEOUT,
+ &(info->CCEusecTimeout))) {
+ /* This option checked by the R128 DRM kernel module */
+ }
+
+ return TRUE;
+}
+#endif
+
extern xf86MonPtr ConfiguredMonitor;
static void
@@ -1152,6 +1379,10 @@ static Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
if (!R128PreInitAccel(pScrn)) goto fail;
+#ifdef XF86DRI
+ if (!R128PreInitDRI(pScrn)) goto fail;
+#endif
+
return TRUE;
fail:
@@ -1231,9 +1462,20 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
R128TRACE(("R128ScreenInit %x %d\n", pScrn->memPhysBase, pScrn->fbOffset));
+#ifdef XF86DRI
+ /* Turn off the CCE for now. */
+ info->CCEInUse = FALSE;
+#endif
+
if (!R128MapMem(pScrn)) return FALSE;
pScrn->fbOffset = 0;
-
+#ifdef XF86DRI
+ info->fbX = 0;
+ info->fbY = 0;
+#endif
+
+ info->PaletteSavedOnVT = FALSE;
+
R128Save(pScrn);
if (info->FBDev) {
if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE;
@@ -1251,6 +1493,18 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
pScrn->rgbBits,
pScrn->defaultVisual)) return FALSE;
+#ifdef XF86DRI
+ /* Setup DRI after visuals have been
+ established, but before cfbScreenInit is
+ called. cfbScreenInit will eventually
+ call the driver's InitGLXVisuals call
+ back. */
+ if (!xf86ReturnOptValBool(R128Options, OPTION_NOACCEL, FALSE))
+ info->directRenderingEnabled = R128DRIScreenInit(pScreen);
+ else
+ info->directRenderingEnabled = FALSE;
+#endif
+
#ifdef USE_FB
if (!fbScreenInit (pScreen, info->FB,
pScrn->virtualX, pScrn->virtualY,
@@ -1358,6 +1612,101 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
}
}
+#ifdef XF86DRI
+ /* Allocate frame buffer space for the
+ shared back and depth buffers as well
+ as for local textures. */
+ if (info->directRenderingEnabled) {
+ FBAreaPtr fbarea;
+ int width_bytes = pScrn->displayWidth * info->pixel_bytes;
+ int maxy = info->FbMapSize / width_bytes;
+ int l;
+
+ /* Allocate the shared back buffer */
+ if ((fbarea = xf86AllocateOffscreenArea(pScreen,
+ pScrn->virtualX,
+ pScrn->virtualY,
+ 32, NULL, NULL, NULL))) {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Reserved back buffer from (%d,%d) to (%d,%d)\n",
+ fbarea->box.x1, fbarea->box.y1,
+ fbarea->box.x2, fbarea->box.y2);
+
+ info->backX = fbarea->box.x1;
+ info->backY = fbarea->box.y1;
+ } else {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve back buffer\n");
+ info->backX = -1;
+ info->backY = -1;
+ }
+
+ /* Allocate the shared depth buffer */
+ if ((fbarea = xf86AllocateOffscreenArea(pScreen,
+ pScrn->virtualX,
+ pScrn->virtualY,
+ 32, NULL, NULL, NULL))) {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Reserved depth buffer from (%d,%d) to (%d,%d)\n",
+ fbarea->box.x1, fbarea->box.y1,
+ fbarea->box.x2, fbarea->box.y2);
+
+ info->depthX = fbarea->box.x1;
+ info->depthY = fbarea->box.y1;
+ } else {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve depth buffer\n");
+ info->depthX = -1;
+ info->depthY = -1;
+ }
+
+ /* Allocate local texture space */
+ if (((maxy - MemBox.y2 - 1) * width_bytes) >
+ (pScrn->virtualX * pScrn->virtualY * 2 * info->pixel_bytes)) {
+ info->textureX = 0;
+ info->textureY = MemBox.y2 + 1;
+ info->textureSize = (maxy - MemBox.y2 - 1) * width_bytes;
+
+ l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS);
+ if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY;
+
+ info->log2TexGran = l;
+ info->textureSize = (info->textureSize >> l) << l;
+
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Reserved %d kb for textures: (%d,%d)-(%d,%d)\n",
+ info->textureSize/1024,
+ info->textureX, info->textureY,
+ pScrn->displayWidth, maxy);
+ } else if ((fbarea = xf86AllocateOffscreenArea(pScreen,
+ pScrn->virtualX,
+ pScrn->virtualY * 2,
+ 32,
+ NULL, NULL, NULL))) {
+ info->textureX = fbarea->box.x1;
+ info->textureY = fbarea->box.y1;
+ info->textureSize = ((fbarea->box.y2 - fbarea->box.y1) *
+ (fbarea->box.x2 - fbarea->box.x1) *
+ info->pixel_bytes);
+
+ l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS);
+ if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY;
+
+ info->log2TexGran = l;
+ info->textureSize = (info->textureSize >> l) << l;
+
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Reserved %d kb for textures: (%d,%d)-(%d,%d)\n",
+ info->textureSize/1024,
+ fbarea->box.x1, fbarea->box.y1,
+ fbarea->box.x2, fbarea->box.y2);
+ } else {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Unable to reserve texture space in frame buffer\n");
+ info->textureX = -1;
+ info->textureY = -1;
+ }
+ }
+#endif
+
/* Backing store setup */
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
@@ -1453,6 +1802,21 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+#ifdef XF86DRI
+ /* DRI finalization */
+ if (info->directRenderingEnabled) {
+ /* Now that mi, cfb, drm and others have
+ done their thing, complete the DRI
+ setup. */
+ info->directRenderingEnabled = R128DRIFinishScreenInit(pScreen);
+ }
+ if (info->directRenderingEnabled) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering disabled\n");
+ }
+#endif
+
return TRUE;
}
@@ -1473,7 +1837,7 @@ static void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
OUTREG(R128_GEN_INT_CNTL, restore->gen_int_cntl);
OUTREG(R128_CAP0_TRIG_CNTL, restore->cap0_trig_cntl);
OUTREG(R128_CAP1_TRIG_CNTL, restore->cap1_trig_cntl);
- OUTREG(R128_BUS_CNTL, restore->bus_cntl);
+ OUTREG(R128_BUS_CNTL, restore->bus_cntl);
}
/* Write CRTC registers. */
@@ -1603,7 +1967,7 @@ static void R128SaveCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr save)
save->gen_int_cntl = INREG(R128_GEN_INT_CNTL);
save->cap0_trig_cntl = INREG(R128_CAP0_TRIG_CNTL);
save->cap1_trig_cntl = INREG(R128_CAP1_TRIG_CNTL);
- save->bus_cntl = INREG(R128_BUS_CNTL);
+ save->bus_cntl = INREG(R128_BUS_CNTL);
}
/* Read CRTC registers. */
@@ -2025,7 +2389,7 @@ static Bool R128Init(ScrnInfoPtr pScrn, DisplayModePtr mode, R128SavePtr save)
R128InitPLLRegisters(pScrn, save, mode, &info->pll, dot_clock);
if (!R128InitDDARegisters(pScrn, save, mode, &info->pll, info))
return FALSE;
- R128InitPalette(save, info);
+ if (!info->PaletteSavedOnVT) R128InitPalette(save, info);
R128TRACE(("R128Init returns %p\n", save));
return TRUE;
@@ -2037,6 +2401,7 @@ static Bool R128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
R128InfoPtr info = R128PTR(pScrn);
if (!R128Init(pScrn, mode, &info->ModeReg)) return FALSE;
+ /* FIXME? DRILock/DRIUnlock here? */
R128Blank(pScrn);
R128RestoreMode(pScrn, &info->ModeReg);
R128Unblank(pScrn);
@@ -2096,14 +2461,43 @@ static void R128AdjustFrame(int scrnIndex, int x, int y, int flags)
mode. */
static Bool R128EnterVT(int scrnIndex, int flags)
{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ R128InfoPtr info = R128PTR(pScrn);
R128TRACE(("R128EnterVT\n"));
+#ifdef XF86DRI
+ if (R128PTR(pScrn)->directRenderingEnabled) {
+ R128CCEStart(pScrn);
+ DRIUnlock(pScrn->pScreen);
+ }
+#endif
if (!R128ModeInit(pScrn, pScrn->currentMode)) return FALSE;
+ info->PaletteSavedOnVT = FALSE;
R128AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
return TRUE;
}
+/* Called when VT switching away from the X server. Restore the original
+ text mode. */
+static void R128LeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ R128InfoPtr info = R128PTR(pScrn);
+ R128SavePtr save = &info->ModeReg;
+
+ R128TRACE(("R128LeaveVT\n"));
+#ifdef XF86DRI
+ if (R128PTR(pScrn)->directRenderingEnabled) {
+ DRILock(pScrn->pScreen, 0);
+ R128CCEStop(pScrn);
+ }
+#endif
+ R128SavePalette(pScrn, save);
+ info->PaletteSavedOnVT = TRUE;
+ R128Restore(pScrn);
+}
+
static Bool
R128EnterVTFBDev(int scrnIndex, int flags)
{
@@ -2116,8 +2510,6 @@ R128EnterVTFBDev(int scrnIndex, int flags)
return TRUE;
}
-/* Called when VT switching away from the X server. Restore the original
- text mode. */
static void R128LeaveVTFBDev(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
@@ -2127,14 +2519,6 @@ static void R128LeaveVTFBDev(int scrnIndex, int flags)
fbdevHWLeaveVT(scrnIndex,flags);
}
-static void R128LeaveVT(int scrnIndex, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-
- R128TRACE(("R128LeaveVT\n"));
- R128Restore(pScrn);
-}
-
/* Called at the end of each server generation. Restore the original text
mode, unmap video memory, and unwrap and call the saved CloseScreen
function. */
@@ -2144,6 +2528,15 @@ static Bool R128CloseScreen(int scrnIndex, ScreenPtr pScreen)
R128InfoPtr info = R128PTR(pScrn);
R128TRACE(("R128CloseScreen\n"));
+
+#ifdef XF86DRI
+ /* Disable direct rendering */
+ if (info->directRenderingEnabled) {
+ R128DRICloseScreen(pScreen);
+ info->directRenderingEnabled = FALSE;
+ }
+#endif
+
if (pScrn->vtSema) {
R128Restore(pScrn);
R128UnmapMem(pScrn);
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h
index 86652affa..144fd9efe 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h
@@ -1,8 +1,8 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h,v 1.6 2000/02/23 04:47:19 martin Exp $ */
/**************************************************************************
-Copyright 1999 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -159,9 +159,20 @@ static inline unsigned short regr16(volatile unsigned long base_addr, unsigned l
#define R128_AGP_APER_OFFSET 0x0178
#define R128_AGP_BASE 0x0170
#define R128_AGP_CNTL 0x0174
+# define R128_AGP_APER_SIZE_256MB (0x00 << 0)
+# define R128_AGP_APER_SIZE_128MB (0x20 << 0)
+# define R128_AGP_APER_SIZE_64MB (0x30 << 0)
+# define R128_AGP_APER_SIZE_32MB (0x38 << 0)
+# define R128_AGP_APER_SIZE_16MB (0x3c << 0)
+# define R128_AGP_APER_SIZE_8MB (0x3e << 0)
+# define R128_AGP_APER_SIZE_4MB (0x3f << 0)
+# define R128_AGP_APER_SIZE_MASK (0x3f << 0)
#define R128_AGP_COMMAND 0x0f58 /* PCI */
#define R128_AGP_PLL_CNTL 0x0010 /* PLL */
#define R128_AGP_STATUS 0x0f54 /* PCI */
+# define R128_AGP_1X_MODE 0x01
+# define R128_AGP_2X_MODE 0x02
+# define R128_AGP_MODE_MASK 0x03
#define R128_AMCGPIO_A_REG 0x01a0
#define R128_AMCGPIO_EN_REG 0x01a8
#define R128_AMCGPIO_MASK 0x0194
@@ -169,6 +180,15 @@ static inline unsigned short regr16(volatile unsigned long base_addr, unsigned l
#define R128_ATTRDR 0x03c1 /* VGA */
#define R128_ATTRDW 0x03c0 /* VGA */
#define R128_ATTRX 0x03c0 /* VGA */
+# define R128_AUX1_SC_EN (1 << 0)
+# define R128_AUX1_SC_MODE_OR (0 << 1)
+# define R128_AUX1_SC_MODE_NAND (1 << 1)
+# define R128_AUX2_SC_EN (1 << 2)
+# define R128_AUX2_SC_MODE_OR (0 << 3)
+# define R128_AUX2_SC_MODE_NAND (1 << 3)
+# define R128_AUX3_SC_EN (1 << 4)
+# define R128_AUX3_SC_MODE_OR (0 << 5)
+# define R128_AUX3_SC_MODE_NAND (1 << 5)
#define R128_AUX_SC_CNTL 0x1660
#define R128_AUX1_SC_BOTTOM 0x1670
#define R128_AUX1_SC_LEFT 0x1664
@@ -257,11 +277,12 @@ static inline unsigned short regr16(volatile unsigned long base_addr, unsigned l
#define R128_BRUSH_SCALE 0x1470
#define R128_BRUSH_Y_X 0x1474
#define R128_BUS_CNTL 0x0030
-# define R128_BUS_RD_DISCARD_EN (1 << 24)
-# define R128_BUS_RD_ABORT_EN (1 << 25)
-# define R128_BUS_MSTR_DISCONNECT_EN (1 << 28)
-# define R128_BUS_WRT_BURST (1 << 29)
-# define R128_BUS_READ_BURST (1 << 30)
+# define R128_BUS_MASTER_DIS (1 << 6)
+# define R128_BUS_RD_DISCARD_EN (1 << 24)
+# define R128_BUS_RD_ABORT_EN (1 << 25)
+# define R128_BUS_MSTR_DISCONNECT_EN (1 << 28)
+# define R128_BUS_WRT_BURST (1 << 29)
+# define R128_BUS_READ_BURST (1 << 30)
#define R128_BUS_CNTL1 0x0034
#define R128_CACHE_CNTL 0x1724
@@ -297,6 +318,9 @@ static inline unsigned short regr16(volatile unsigned long base_addr, unsigned l
#define R128_CONFIG_REG_APER_SIZE 0x0110
#define R128_CONFIG_XSTRAP 0x00e4
#define R128_CONSTANT_COLOR_C 0x1d34
+# define R128_CONSTANT_COLOR_MASK 0x00ffffff
+# define R128_CONSTANT_COLOR_ONE 0x00ffffff
+# define R128_CONSTANT_COLOR_ZERO 0x00000000
#define R128_CRC_CMDFIFO_ADDR 0x0740
#define R128_CRC_CMDFIFO_DOUT 0x0744
#define R128_CRTC_CRNT_FRAME 0x0214
@@ -360,8 +384,13 @@ static inline unsigned short regr16(volatile unsigned long base_addr, unsigned l
#define R128_DEFAULT_SC_BOTTOM_RIGHT 0x16e8
# define R128_DEFAULT_SC_RIGHT_MAX (0x1fff << 0)
# define R128_DEFAULT_SC_BOTTOM_MAX (0x1fff << 16)
-#define R128_DESTINATION_3D_CLR_CMP_MSK 0x1824
+#define R128_FOG_3D_TABLE_START 0x1810
+#define R128_FOG_3D_TABLE_END 0x1814
+#define R128_FOG_3D_TABLE_DENSITY 0x181c
+#define R128_FOG_TABLE_INDEX 0x1a14
+#define R128_FOG_TABLE_DATA 0x1a18
#define R128_DESTINATION_3D_CLR_CMP_VAL 0x1820
+#define R128_DESTINATION_3D_CLR_CMP_MSK 0x1824
#define R128_DEVICE_ID 0x0f02 /* PCI */
#define R128_DP_BRUSH_BKGD_CLR 0x1478
#define R128_DP_BRUSH_FRGD_CLR 0x147c
@@ -373,6 +402,7 @@ static inline unsigned short regr16(volatile unsigned long base_addr, unsigned l
# define R128_DST_Y_DIR_TOP_TO_BOTTOM (1 << 15)
# define R128_DST_X_DIR_LEFT_TO_RIGHT (1 << 31)
#define R128_DP_DATATYPE 0x16c4
+# define R128_HOST_BIG_ENDIAN_EN (1 << 29)
#define R128_DP_GUI_MASTER_CNTL 0x146c
# define R128_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
# define R128_GMC_DST_PITCH_OFFSET_CNTL (1 << 1)
@@ -388,6 +418,19 @@ static inline unsigned short regr16(volatile unsigned long base_addr, unsigned l
# define R128_GMC_BRUSH_8x8_COLOR (10 << 4)
# define R128_GMC_BRUSH_1X8_COLOR (12 << 4)
# define R128_GMC_BRUSH_SOLID_COLOR (13 << 4)
+# define R128_GMC_BRUSH_NONE (15 << 4)
+# define R128_GMC_DST_8BPP_CI (2 << 8)
+# define R128_GMC_DST_15BPP (3 << 8)
+# define R128_GMC_DST_16BPP (4 << 8)
+# define R128_GMC_DST_24BPP (5 << 8)
+# define R128_GMC_DST_32BPP (6 << 8)
+# define R128_GMC_DST_8BPP_RGB (7 << 8)
+# define R128_GMC_DST_Y8 (8 << 8)
+# define R128_GMC_DST_RGB8 (9 << 8)
+# define R128_GMC_DST_VYUY (11 << 8)
+# define R128_GMC_DST_YVYU (12 << 8)
+# define R128_GMC_DST_AYUV444 (14 << 8)
+# define R128_GMC_DST_ARGB4444 (15 << 8)
# define R128_GMC_DST_DATATYPE_MASK (0x0f << 8)
# define R128_GMC_DST_DATATYPE_SHIFT 8
# define R128_GMC_SRC_DATATYPE_MASK (3 << 12)
@@ -395,8 +438,11 @@ static inline unsigned short regr16(volatile unsigned long base_addr, unsigned l
# define R128_GMC_SRC_DATATYPE_MONO_FG_LA (1 << 12)
# define R128_GMC_SRC_DATATYPE_COLOR (3 << 12)
# define R128_GMC_BYTE_PIX_ORDER (1 << 14)
+# define R128_GMC_BYTE_MSB_TO_LSB (0 << 14)
# define R128_GMC_BYTE_LSB_TO_MSB (1 << 14)
# define R128_GMC_CONVERSION_TEMP (1 << 15)
+# define R128_GMC_CONVERSION_TEMP_6500 (0 << 15)
+# define R128_GMC_CONVERSION_TEMP_9300 (1 << 15)
# define R128_GMC_ROP3_MASK (0xff << 16)
# define R128_DP_SRC_SOURCE_MASK (7 << 24)
# define R128_DP_SRC_SOURCE_MEMORY (2 << 24)
@@ -404,7 +450,7 @@ static inline unsigned short regr16(volatile unsigned long base_addr, unsigned l
# define R128_GMC_3D_FCN_EN (1 << 27)
# define R128_GMC_CLR_CMP_CNTL_DIS (1 << 28)
# define R128_AUX_CLIP_DIS (1 << 29)
-# define R128_GMC_WR_MSK_DS (1 << 30)
+# define R128_GMC_WR_MSK_DIS (1 << 30)
# define R128_GMC_LD_BRUSH_Y_X (1 << 31)
# define R128_ROP3_ZERO 0x00000000
# define R128_ROP3_DSa 0x00880000
@@ -456,6 +502,7 @@ static inline unsigned short regr16(volatile unsigned long base_addr, unsigned l
#define R128_DST_PITCH 0x1408
#define R128_DST_PITCH_OFFSET 0x142c
#define R128_DST_PITCH_OFFSET_C 0x1c80
+# define R128_PITCH_SHIFT 21
#define R128_DST_WIDTH 0x140c
#define R128_DST_WIDTH_HEIGHT 0x1598
#define R128_DST_WIDTH_X 0x1588
@@ -573,7 +620,6 @@ static inline unsigned short regr16(volatile unsigned long base_addr, unsigned l
#define R128_MEM_VGA_RP_SEL 0x003c
#define R128_MEM_VGA_WP_SEL 0x0038
#define R128_MIN_GRANT 0x0f3e /* PCI */
-#define R128_MISC_3D_STATE_CNTL_REG 0x1CA0
#define R128_MM_DATA 0x0004
#define R128_MM_INDEX 0x0000
#define R128_MPLL_CNTL 0x000e /* PLL */
@@ -592,7 +638,10 @@ static inline unsigned short regr16(volatile unsigned long base_addr, unsigned l
#define R128_PC_DEBUG_MODE 0x1760
#define R128_PC_GUI_CTLSTAT 0x1748
#define R128_PC_GUI_MODE 0x1744
+# define R128_PC_IGNORE_UNIFY (1 << 5)
#define R128_PC_NGUI_CTLSTAT 0x0184
+# define R128_PC_FLUSH_GUI (3 << 0)
+# define R128_PC_RI_GUI (1 << 2)
# define R128_PC_FLUSH_ALL 0x00ff
# define R128_PC_BUSY (1 << 31)
#define R128_PC_NGUI_MODE 0x0180
@@ -689,6 +738,538 @@ static inline unsigned short regr16(volatile unsigned long base_addr, unsigned l
#define R128_XDLL_CNTL 0x000c /* PLL */
#define R128_XPLL_CNTL 0x000b /* PLL */
+ /* Registers for CCE and Microcode Engine */
+#define R128_PM4_MICROCODE_ADDR 0x07d4
+#define R128_PM4_MICROCODE_RADDR 0x07d8
+#define R128_PM4_MICROCODE_DATAH 0x07dc
+#define R128_PM4_MICROCODE_DATAL 0x07e0
+
+#define R128_PM4_BUFFER_OFFSET 0x0700
+#define R128_PM4_BUFFER_CNTL 0x0704
+# define R128_PM4_NONPM4 (0 << 28)
+# define R128_PM4_192PIO (1 << 28)
+# define R128_PM4_192BM (2 << 28)
+# define R128_PM4_128PIO_64INDBM (3 << 28)
+# define R128_PM4_128BM_64INDBM (4 << 28)
+# define R128_PM4_64PIO_128INDBM (5 << 28)
+# define R128_PM4_64BM_128INDBM (6 << 28)
+# define R128_PM4_64PIO_64VCBM_64INDBM (7 << 28)
+# define R128_PM4_64BM_64VCBM_64INDBM (8 << 28)
+# define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28)
+#define R128_PM4_BUFFER_WM_CNTL 0x0708
+# define R128_WMA_SHIFT 0
+# define R128_WMB_SHIFT 8
+# define R128_WMC_SHIFT 16
+# define R128_WB_WM_SHIFT 24
+#define R128_PM4_BUFFER_DL_RPTR_ADDR 0x070c
+#define R128_PM4_BUFFER_DL_RPTR 0x0710
+#define R128_PM4_BUFFER_DL_WPTR 0x0714
+# define R128_PM4_BUFFER_DL_DONE (1 << 31)
+#define R128_PM4_VC_FPU_SETUP 0x071c
+# define R128_FRONT_DIR_CW (0 << 0)
+# define R128_FRONT_DIR_CCW (1 << 0)
+# define R128_FRONT_DIR_MASK (1 << 0)
+# define R128_BACKFACE_CULL (0 << 1)
+# define R128_BACKFACE_POINTS (1 << 1)
+# define R128_BACKFACE_LINES (2 << 1)
+# define R128_BACKFACE_SOLID (3 << 1)
+# define R128_BACKFACE_MASK (3 << 1)
+# define R128_FRONTFACE_CULL (0 << 3)
+# define R128_FRONTFACE_POINTS (1 << 3)
+# define R128_FRONTFACE_LINES (2 << 3)
+# define R128_FRONTFACE_SOLID (3 << 3)
+# define R128_FRONTFACE_MASK (3 << 3)
+# define R128_FPU_COLOR_SOLID (0 << 5)
+# define R128_FPU_COLOR_FLAT (1 << 5)
+# define R128_FPU_COLOR_GOURAUD (2 << 5)
+# define R128_FPU_COLOR_GOURAUD2 (3 << 5)
+# define R128_FPU_SUB_PIX_2BITS (0 << 7)
+# define R128_FPU_SUB_PIX_4BITS (1 << 7)
+# define R128_FPU_MODE_2D (0 << 8)
+# define R128_FPU_MODE_3D (1 << 8)
+# define R128_TRAP_BITS_DISABLE (1 << 9)
+# define R128_EDGE_ANTIALIAS (1 << 10)
+# define R128_SUPERSAMPLE (1 << 11)
+# define R128_XFACTOR_2 (0 << 12)
+# define R128_XFACTOR_4 (1 << 12)
+# define R128_YFACTOR_2 (0 << 13)
+# define R128_YFACTOR_4 (1 << 13)
+# define R128_FLAT_SHADE_VERTEX_D3D (0 << 14)
+# define R128_FLAT_SHADE_VERTEX_OGL (1 << 14)
+# define R128_FPU_ROUND_TRUNCATE (0 << 15)
+# define R128_FPU_ROUND_NEAREST (1 << 15)
+# define R128_WM_SEL_8DW (0 << 16)
+# define R128_WM_SEL_16DW (1 << 16)
+# define R128_WM_SEL_32DW (2 << 16)
+#define R128_PM4_STAT 0x07b8
+# define R128_PM4_FIFOCNT_MASK 0x0fff
+# define R128_PM4_BUSY (1 << 16)
+# define R128_PM4_GUI_ACTIVE (1 << 31)
+#define R128_PM4_BUFFER_ADDR 0x07f0
+#define R128_PM4_MICRO_CNTL 0x07fc
+# define R128_PM4_MICRO_FREERUN (1 << 30)
+#define R128_PM4_FIFO_DATA_EVEN 0x1000
+#define R128_PM4_FIFO_DATA_ODD 0x1004
+
#define R128_SCALE_3D_CNTL 0x1a00
+# define R128_SCALE_DITHER_ERR_DIFF (0 << 1)
+# define R128_SCALE_DITHER_TABLE (1 << 1)
+# define R128_TEX_CACHE_SIZE_FULL (0 << 2)
+# define R128_TEX_CACHE_SIZE_HALF (1 << 2)
+# define R128_DITHER_INIT_CURR (0 << 3)
+# define R128_DITHER_INIT_RESET (1 << 3)
+# define R128_ROUND_24BIT (1 << 4)
+# define R128_TEX_CACHE_DISABLE (1 << 5)
+# define R128_SCALE_3D_NOOP (0 << 6)
+# define R128_SCALE_3D_SCALE (1 << 6)
+# define R128_SCALE_3D_TEXMAP_SHADE (2 << 6)
+# define R128_SCALE_PIX_BLEND (0 << 8)
+# define R128_SCALE_PIX_REPLICATE (1 << 8)
+# define R128_TEX_CACHE_SPLIT (1 << 9)
+# define R128_APPLE_YUV_MODE (1 << 10)
+# define R128_TEX_CACHE_PALLETE_MODE (1 << 11)
+# define R128_ALPHA_COMB_ADD_CLAMP (0 << 12)
+# define R128_ALPHA_COMB_ADD_NCLAMP (1 << 12)
+# define R128_ALPHA_COMB_SUB_DST_SRC_CLAMP (2 << 12)
+# define R128_ALPHA_COMB_SUB_DST_SRC_NCLAMP (3 << 12)
+# define R128_FOG_TABLE (1 << 14)
+# define R128_SIGNED_DST_CLAMP (1 << 15)
+# define R128_ALPHA_BLEND_SRC_ZERO (0 << 16)
+# define R128_ALPHA_BLEND_SRC_ONE (1 << 16)
+# define R128_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16)
+# define R128_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16)
+# define R128_ALPHA_BLEND_SRC_SRCALPHA (4 << 16)
+# define R128_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16)
+# define R128_ALPHA_BLEND_SRC_DSTALPHA (6 << 16)
+# define R128_ALPHA_BLEND_SRC_INVDSTALPHA (7 << 16)
+# define R128_ALPHA_BLEND_SRC_DSTCOLOR (8 << 16)
+# define R128_ALPHA_BLEND_SRC_INVDSTCOLOR (9 << 16)
+# define R128_ALPHA_BLEND_SRC_SAT (10 << 16)
+# define R128_ALPHA_BLEND_SRC_BLEND (11 << 16)
+# define R128_ALPHA_BLEND_SRC_INVBLEND (12 << 16)
+# define R128_ALPHA_BLEND_DST_ZERO (0 << 20)
+# define R128_ALPHA_BLEND_DST_ONE (1 << 20)
+# define R128_ALPHA_BLEND_DST_SRCCOLOR (2 << 20)
+# define R128_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20)
+# define R128_ALPHA_BLEND_DST_SRCALPHA (4 << 20)
+# define R128_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20)
+# define R128_ALPHA_BLEND_DST_DSTALPHA (6 << 20)
+# define R128_ALPHA_BLEND_DST_INVDSTALPHA (7 << 20)
+# define R128_ALPHA_BLEND_DST_DSTCOLOR (8 << 20)
+# define R128_ALPHA_BLEND_DST_INVDSTCOLOR (9 << 20)
+# define R128_ALPHA_TEST_NEVER (0 << 24)
+# define R128_ALPHA_TEST_LESS (1 << 24)
+# define R128_ALPHA_TEST_LESSEQUAL (2 << 24)
+# define R128_ALPHA_TEST_EQUAL (3 << 24)
+# define R128_ALPHA_TEST_GREATEREQUAL (4 << 24)
+# define R128_ALPHA_TEST_GREATER (5 << 24)
+# define R128_ALPHA_TEST_NEQUAL (6 << 24)
+# define R128_ALPHA_TEST_ALWAYS (7 << 24)
+# define R128_COMPOSITE_SHADOW_CMP_EQUAL (0 << 28)
+# define R128_COMPOSITE_SHADOW_CMP_NEQUAL (1 << 28)
+# define R128_COMPOSITE_SHADOW (1 << 29)
+# define R128_TEX_MAP_ALPHA_IN_TEXTURE (1 << 30)
+# define R128_TEX_CACHE_LINE_SIZE_8QW (0 << 31)
+# define R128_TEX_CACHE_LINE_SIZE_4QW (1 << 31)
+
+#define R128_SETUP_CNTL 0x1bc4
+# define R128_DONT_START_TRIANGLE (1 << 0)
+# define R128_Z_BIAS (0 << 1)
+# define R128_DONT_START_ANY_ON (1 << 2)
+# define R128_COLOR_SOLID_COLOR (0 << 3)
+# define R128_COLOR_FLAT_VERT_1 (1 << 3)
+# define R128_COLOR_FLAT_VERT_2 (2 << 3)
+# define R128_COLOR_FLAT_VERT_3 (3 << 3)
+# define R128_COLOR_GOURAUD (4 << 3)
+# define R128_PRIM_TYPE_TRI (0 << 7)
+# define R128_PRIM_TYPE_LINE (1 << 7)
+# define R128_PRIM_TYPE_POINT (2 << 7)
+# define R128_PRIM_TYPE_POLY_EDGE (3 << 7)
+# define R128_TEXTURE_ST_MULT_W (0 << 9)
+# define R128_TEXTURE_ST_DIRECT (1 << 9)
+# define R128_STARTING_VERTEX_1 (1 << 14)
+# define R128_STARTING_VERTEX_2 (2 << 14)
+# define R128_STARTING_VERTEX_3 (3 << 14)
+# define R128_ENDING_VERTEX_1 (1 << 16)
+# define R128_ENDING_VERTEX_2 (2 << 16)
+# define R128_ENDING_VERTEX_3 (3 << 16)
+# define R128_SU_POLY_LINE_LAST (0 << 18)
+# define R128_SU_POLY_LINE_NOT_LAST (1 << 18)
+# define R128_SUB_PIX_2BITS (0 << 19)
+# define R128_SUB_PIX_4BITS (1 << 19)
+# define R128_SET_UP_CONTINUE (1 << 31)
+
+#define R128_WINDOW_XY_OFFSET 0x1bcc
+# define R128_WINDOW_Y_SHIFT 4
+# define R128_WINDOW_X_SHIFT 20
+
+#define R128_Z_OFFSET_C 0x1c90
+#define R128_Z_PITCH_C 0x1c94
+#define R128_Z_STEN_CNTL_C 0x1c98
+# define R128_Z_PIX_WIDTH_16 (0 << 1)
+# define R128_Z_PIX_WIDTH_24 (1 << 1)
+# define R128_Z_PIX_WIDTH_32 (2 << 1)
+# define R128_Z_PIX_WIDTH_MASK (3 << 1)
+# define R128_Z_TEST_NEVER (0 << 4)
+# define R128_Z_TEST_LESS (1 << 4)
+# define R128_Z_TEST_LESSEQUAL (2 << 4)
+# define R128_Z_TEST_EQUAL (3 << 4)
+# define R128_Z_TEST_GREATEREQUAL (4 << 4)
+# define R128_Z_TEST_GREATER (5 << 4)
+# define R128_Z_TEST_NEQUAL (6 << 4)
+# define R128_Z_TEST_ALWAYS (7 << 4)
+# define R128_Z_TEST_MASK (7 << 4)
+# define R128_STENCIL_TEST_NEVER (0 << 12)
+# define R128_STENCIL_TEST_LESS (1 << 12)
+# define R128_STENCIL_TEST_LESSEQUAL (2 << 12)
+# define R128_STENCIL_TEST_EQUAL (3 << 12)
+# define R128_STENCIL_TEST_GREATEREQUAL (4 << 12)
+# define R128_STENCIL_TEST_GREATER (5 << 12)
+# define R128_STENCIL_TEST_NEQUAL (6 << 12)
+# define R128_STENCIL_TEST_ALWAYS (7 << 12)
+# define R128_STENCIL_S_FAIL_KEEP (0 << 16)
+# define R128_STENCIL_S_FAIL_ZERO (1 << 16)
+# define R128_STENCIL_S_FAIL_REPLACE (2 << 16)
+# define R128_STENCIL_S_FAIL_INC (3 << 16)
+# define R128_STENCIL_S_FAIL_DEC (4 << 16)
+# define R128_STENCIL_S_FAIL_INV (5 << 16)
+# define R128_STENCIL_ZPASS_KEEP (0 << 20)
+# define R128_STENCIL_ZPASS_ZERO (1 << 20)
+# define R128_STENCIL_ZPASS_REPLACE (2 << 20)
+# define R128_STENCIL_ZPASS_INC (3 << 20)
+# define R128_STENCIL_ZPASS_DEC (4 << 20)
+# define R128_STENCIL_ZPASS_INV (5 << 20)
+# define R128_STENCIL_ZFAIL_KEEP (0 << 24)
+# define R128_STENCIL_ZFAIL_ZERO (1 << 24)
+# define R128_STENCIL_ZFAIL_REPLACE (2 << 24)
+# define R128_STENCIL_ZFAIL_INC (3 << 24)
+# define R128_STENCIL_ZFAIL_DEC (4 << 24)
+# define R128_STENCIL_ZFAIL_INV (5 << 24)
+#define R128_TEX_CNTL_C 0x1c9c
+# define R128_Z_ENABLE (1 << 0)
+# define R128_Z_WRITE_ENABLE (1 << 1)
+# define R128_STENCIL_ENABLE (1 << 3)
+# define R128_SHADE_ENABLE (0 << 4)
+# define R128_TEXMAP_ENABLE (1 << 4)
+# define R128_SEC_TEXMAP_ENABLE (1 << 5)
+# define R128_FOG_ENABLE (1 << 7)
+# define R128_DITHER_ENABLE (1 << 8)
+# define R128_ALPHA_ENABLE (1 << 9)
+# define R128_ALPHA_TEST_ENABLE (1 << 10)
+# define R128_SPEC_LIGHT_ENABLE (1 << 11)
+# define R128_TEX_CHROMA_KEY_ENABLE (1 << 12)
+# define R128_ALPHA_IN_TEX_COMPLETE_A (0 << 13)
+# define R128_ALPHA_IN_TEX_LSB_A (1 << 13)
+# define R128_LIGHT_DIS (0 << 14)
+# define R128_LIGHT_COPY (1 << 14)
+# define R128_LIGHT_MODULATE (2 << 14)
+# define R128_LIGHT_ADD (3 << 14)
+# define R128_LIGHT_BLEND_CONSTANT (4 << 14)
+# define R128_LIGHT_BLEND_TEXTURE (5 << 14)
+# define R128_LIGHT_BLEND_VERTEX (6 << 14)
+# define R128_LIGHT_BLEND_CONST_COLOR (7 << 14)
+# define R128_ALPHA_LIGHT_DIS (0 << 18)
+# define R128_ALPHA_LIGHT_COPY (1 << 18)
+# define R128_ALPHA_LIGHT_MODULATE (2 << 18)
+# define R128_ALPHA_LIGHT_ADD (3 << 18)
+# define R128_ANTI_ALIAS (1 << 21)
+# define R128_TEX_CACHE_FLUSH (1 << 23)
+# define R128_LOD_BIAS_SHIFT 24
+#define R128_MISC_3D_STATE_CNTL_REG 0x1ca0
+# define R128_REF_ALPHA_MASK 0xff
+# define R128_MISC_SCALE_3D_NOOP (0 << 8)
+# define R128_MISC_SCALE_3D_SCALE (1 << 8)
+# define R128_MISC_SCALE_3D_TEXMAP_SHADE (2 << 8)
+# define R128_MISC_SCALE_PIX_BLEND (0 << 10)
+# define R128_MISC_SCALE_PIX_REPLICATE (1 << 10)
+# define R128_ALPHA_COMB_ADD_CLAMP (0 << 12)
+# define R128_ALPHA_COMB_ADD_NO_CLAMP (1 << 12)
+# define R128_ALPHA_COMB_SUB_SRC_DST_CLAMP (2 << 12)
+# define R128_ALPHA_COMB_SUB_SRC_DST_NO_CLAMP (3 << 12)
+# define R128_FOG_VERTEX (0 << 14)
+# define R128_FOG_TABLE (1 << 14)
+# define R128_ALPHA_BLEND_SRC_ZERO (0 << 16)
+# define R128_ALPHA_BLEND_SRC_ONE (1 << 16)
+# define R128_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16)
+# define R128_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16)
+# define R128_ALPHA_BLEND_SRC_SRCALPHA (4 << 16)
+# define R128_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16)
+# define R128_ALPHA_BLEND_SRC_DESTALPHA (6 << 16)
+# define R128_ALPHA_BLEND_SRC_INVDESTALPHA (7 << 16)
+# define R128_ALPHA_BLEND_SRC_DESTCOLOR (8 << 16)
+# define R128_ALPHA_BLEND_SRC_INVDESTCOLOR (9 << 16)
+# define R128_ALPHA_BLEND_SRC_SRCALPHASAT (10 << 16)
+# define R128_ALPHA_BLEND_SRC_BOTHSRCALPHA (11 << 16)
+# define R128_ALPHA_BLEND_SRC_BOTHINVSRCALPHA (12 << 16)
+# define R128_ALPHA_BLEND_SRC_MASK (15 << 16)
+# define R128_ALPHA_BLEND_DST_ZERO (0 << 20)
+# define R128_ALPHA_BLEND_DST_ONE (1 << 20)
+# define R128_ALPHA_BLEND_DST_SRCCOLOR (2 << 20)
+# define R128_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20)
+# define R128_ALPHA_BLEND_DST_SRCALPHA (4 << 20)
+# define R128_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20)
+# define R128_ALPHA_BLEND_DST_DESTALPHA (6 << 20)
+# define R128_ALPHA_BLEND_DST_INVDESTALPHA (7 << 20)
+# define R128_ALPHA_BLEND_DST_DESTCOLOR (8 << 20)
+# define R128_ALPHA_BLEND_DST_INVDESTCOLOR (9 << 20)
+# define R128_ALPHA_BLEND_DST_SRCALPHASAT (10 << 20)
+# define R128_ALPHA_BLEND_DST_MASK (15 << 20)
+# define R128_ALPHA_TEST_NEVER (0 << 24)
+# define R128_ALPHA_TEST_LESS (1 << 24)
+# define R128_ALPHA_TEST_LESSEQUAL (2 << 24)
+# define R128_ALPHA_TEST_EQUAL (3 << 24)
+# define R128_ALPHA_TEST_GREATEREQUAL (4 << 24)
+# define R128_ALPHA_TEST_GREATER (5 << 24)
+# define R128_ALPHA_TEST_NEQUAL (6 << 24)
+# define R128_ALPHA_TEST_ALWAYS (7 << 24)
+# define R128_ALPHA_TEST_MASK (7 << 24)
+#define R128_TEXTURE_CLR_CMP_CLR_C 0x1ca4
+#define R128_TEXTURE_CLR_CMP_MSK_C 0x1ca8
+#define R128_FOG_COLOR_C 0x1cac
+# define R128_FOG_BLUE_SHIFT 0
+# define R128_FOG_GREEN_SHIFT 8
+# define R128_FOG_RED_SHIFT 16
+#define R128_PRIM_TEX_CNTL_C 0x1cb0
+# define R128_MIN_BLEND_NEAREST (0 << 1)
+# define R128_MIN_BLEND_LINEAR (1 << 1)
+# define R128_MIN_BLEND_MIPNEAREST (2 << 1)
+# define R128_MIN_BLEND_MIPLINEAR (3 << 1)
+# define R128_MIN_BLEND_LINEARMIPNEAREST (4 << 1)
+# define R128_MIN_BLEND_LINEARMIPLINEAR (5 << 1)
+# define R128_MIN_BLEND_MASK (7 << 1)
+# define R128_MAG_BLEND_NEAREST (0 << 4)
+# define R128_MAG_BLEND_LINEAR (1 << 4)
+# define R128_MAG_BLEND_MASK (7 << 4)
+# define R128_MIP_MAP_DISABLE (1 << 7)
+# define R128_TEX_CLAMP_S_WRAP (0 << 8)
+# define R128_TEX_CLAMP_S_MIRROR (1 << 8)
+# define R128_TEX_CLAMP_S_CLAMP (2 << 8)
+# define R128_TEX_CLAMP_S_BORDER_COLOR (3 << 8)
+# define R128_TEX_CLAMP_S_MASK (3 << 8)
+# define R128_TEX_WRAP_S (1 << 10)
+# define R128_TEX_CLAMP_T_WRAP (0 << 11)
+# define R128_TEX_CLAMP_T_MIRROR (1 << 11)
+# define R128_TEX_CLAMP_T_CLAMP (2 << 11)
+# define R128_TEX_CLAMP_T_BORDER_COLOR (3 << 11)
+# define R128_TEX_CLAMP_T_MASK (3 << 11)
+# define R128_TEX_WRAP_T (1 << 13)
+# define R128_TEX_PERSPECTIVE_DISABLE (1 << 14)
+# define R128_DATATYPE_VQ (0 << 16)
+# define R128_DATATYPE_CI4 (1 << 16)
+# define R128_DATATYPE_CI8 (2 << 16)
+# define R128_DATATYPE_ARGB1555 (3 << 16)
+# define R128_DATATYPE_RGB565 (4 << 16)
+# define R128_DATATYPE_RGB888 (5 << 16)
+# define R128_DATATYPE_ARGB8888 (6 << 16)
+# define R128_DATATYPE_RGB332 (7 << 16)
+# define R128_DATATYPE_Y8 (8 << 16)
+# define R128_DATATYPE_RGB8 (9 << 16)
+# define R128_DATATYPE_CI16 (10 << 16)
+# define R128_DATATYPE_YUV422 (11 << 16)
+# define R128_DATATYPE_YUV422_2 (12 << 16)
+# define R128_DATATYPE_AYUV444 (14 << 16)
+# define R128_DATATYPE_ARGB4444 (15 << 16)
+# define R128_PALLETE_EITHER (0 << 20)
+# define R128_PALLETE_1 (1 << 20)
+# define R128_PALLETE_2 (2 << 20)
+# define R128_PSEUDOCOLOR_DT_RGB565 (0 << 24)
+# define R128_PSEUDOCOLOR_DT_ARGB1555 (1 << 24)
+# define R128_PSEUDOCOLOR_DT_ARGB4444 (2 << 24)
+#define R128_PRIM_TEXTURE_COMBINE_CNTL_C 0x1cb4
+# define R128_COMB_DIS (0 << 0)
+# define R128_COMB_COPY (1 << 0)
+# define R128_COMB_COPY_INP (2 << 0)
+# define R128_COMB_MODULATE (3 << 0)
+# define R128_COMB_MODULATE2X (4 << 0)
+# define R128_COMB_MODULATE4X (5 << 0)
+# define R128_COMB_ADD (6 << 0)
+# define R128_COMB_ADD_SIGNED (7 << 0)
+# define R128_COMB_BLEND_VERTEX (8 << 0)
+# define R128_COMB_BLEND_TEXTURE (9 << 0)
+# define R128_COMB_BLEND_CONST (10 << 0)
+# define R128_COMB_BLEND_PREMULT (11 << 0)
+# define R128_COMB_BLEND_PREV (12 << 0)
+# define R128_COMB_BLEND_PREMULT_INV (13 << 0)
+# define R128_COMB_ADD_SIGNED2X (14 << 0)
+# define R128_COMB_BLEND_CONST_COLOR (15 << 0)
+# define R128_COMB_MASK (15 << 0)
+# define R128_COLOR_FACTOR_TEX (4 << 4)
+# define R128_COLOR_FACTOR_NTEX (5 << 4)
+# define R128_COLOR_FACTOR_ALPHA (6 << 4)
+# define R128_COLOR_FACTOR_NALPHA (7 << 4)
+# define R128_COLOR_FACTOR_MASK (15 << 4)
+# define R128_INPUT_FACTOR_CONST_COLOR (2 << 10)
+# define R128_INPUT_FACTOR_CONST_ALPHA (3 << 10)
+# define R128_INPUT_FACTOR_INT_COLOR (4 << 10)
+# define R128_INPUT_FACTOR_INT_ALPHA (5 << 10)
+# define R128_INPUT_FACTOR_MASK (15 << 10)
+# define R128_COMB_ALPHA_DIS (0 << 14)
+# define R128_COMB_ALPHA_COPY (1 << 14)
+# define R128_COMB_ALPHA_COPY_INP (2 << 14)
+# define R128_COMB_ALPHA_MODULATE (3 << 14)
+# define R128_COMB_ALPHA_MODULATE2X (4 << 14)
+# define R128_COMB_ALPHA_MODULATE4X (5 << 14)
+# define R128_COMB_ALPHA_ADD (6 << 14)
+# define R128_COMB_ALPHA_ADD_SIGNED (7 << 14)
+# define R128_COMB_ALPHA_ADD_SIGNED2X (14 << 14)
+# define R128_COMB_ALPHA_MASK (15 << 14)
+# define R128_ALPHA_FACTOR_TEX_ALPHA (6 << 18)
+# define R128_ALPHA_FACTOR_NTEX_ALPHA (7 << 18)
+# define R128_ALPHA_FACTOR_MASK (15 << 18)
+# define R128_INP_FACTOR_A_CONST_ALPHA (1 << 25)
+# define R128_INP_FACTOR_A_INT_ALPHA (2 << 25)
+# define R128_INP_FACTOR_A_MASK (7 << 25)
+#define R128_TEX_SIZE_PITCH_C 0x1cb8
+# define R128_TEX_PITCH_SHIFT 0
+# define R128_TEX_SIZE_SHIFT 4
+# define R128_TEX_HEIGHT_SHIFT 8
+# define R128_TEX_MIN_SIZE_SHIFT 12
+# define R128_SEC_TEX_PITCH_SHIFT 16
+# define R128_SEC_TEX_SIZE_SHIFT 20
+# define R128_SEC_TEX_HEIGHT_SHIFT 24
+# define R128_SEC_TEX_MIN_SIZE_SHIFT 28
+# define R128_TEX_PITCH_MASK (0x0f << 0)
+# define R128_TEX_SIZE_MASK (0x0f << 4)
+# define R128_TEX_HEIGHT_MASK (0x0f << 8)
+# define R128_TEX_MIN_SIZE_MASK (0x0f << 12)
+# define R128_SEC_TEX_PITCH_MASK (0x0f << 16)
+# define R128_SEC_TEX_SIZE_MASK (0x0f << 20)
+# define R128_SEC_TEX_HEIGHT_MASK (0x0f << 24)
+# define R128_SEC_TEX_MIN_SIZE_MASK (0x0f << 28)
+# define R128_TEX_SIZE_PITCH_SHIFT 0
+# define R128_SEC_TEX_SIZE_PITCH_SHIFT 16
+# define R128_TEX_SIZE_PITCH_MASK (0xffff << 0)
+# define R128_SEC_TEX_SIZE_PITCH_MASK (0xffff << 16)
+#define R128_PRIM_TEX_0_OFFSET_C 0x1cbc
+#define R128_PRIM_TEX_1_OFFSET_C 0x1cc0
+#define R128_PRIM_TEX_2_OFFSET_C 0x1cc4
+#define R128_PRIM_TEX_3_OFFSET_C 0x1cc8
+#define R128_PRIM_TEX_4_OFFSET_C 0x1ccc
+#define R128_PRIM_TEX_5_OFFSET_C 0x1cd0
+#define R128_PRIM_TEX_6_OFFSET_C 0x1cd4
+#define R128_PRIM_TEX_7_OFFSET_C 0x1cd8
+#define R128_PRIM_TEX_8_OFFSET_C 0x1cdc
+#define R128_PRIM_TEX_9_OFFSET_C 0x1ce0
+#define R128_PRIM_TEX_10_OFFSET_C 0x1ce4
+# define R128_TEX_NO_TILE (0 << 30)
+# define R128_TEX_TILED_BY_HOST (1 << 30)
+# define R128_TEX_TILED_BY_STORAGE (2 << 30)
+# define R128_TEX_TILED_BY_STORAGE2 (3 << 30)
+
+#define R128_SEC_TEX_CNTL_C 0x1d00
+# define R128_SEC_SELECT_PRIM_ST (0 << 0)
+# define R128_SEC_SELECT_SEC_ST (1 << 0)
+#define R128_SEC_TEX_COMBINE_CNTL_C 0x1d04
+# define R128_INPUT_FACTOR_PREV_COLOR (8 << 10)
+# define R128_INPUT_FACTOR_PREV_ALPHA (9 << 10)
+# define R128_INP_FACTOR_A_PREV_ALPHA (4 << 25)
+#define R128_SEC_TEX_0_OFFSET_C 0x1d08
+#define R128_SEC_TEX_1_OFFSET_C 0x1d0c
+#define R128_SEC_TEX_2_OFFSET_C 0x1d10
+#define R128_SEC_TEX_3_OFFSET_C 0x1d14
+#define R128_SEC_TEX_4_OFFSET_C 0x1d18
+#define R128_SEC_TEX_5_OFFSET_C 0x1d1c
+#define R128_SEC_TEX_6_OFFSET_C 0x1d20
+#define R128_SEC_TEX_7_OFFSET_C 0x1d24
+#define R128_SEC_TEX_8_OFFSET_C 0x1d28
+#define R128_SEC_TEX_9_OFFSET_C 0x1d2c
+#define R128_SEC_TEX_10_OFFSET_C 0x1d30
+#define R128_CONSTANT_COLOR_C 0x1d34
+# define R128_CONSTANT_BLUE_SHIFT 0
+# define R128_CONSTANT_GREEN_SHIFT 8
+# define R128_CONSTANT_RED_SHIFT 16
+# define R128_CONSTANT_ALPHA_SHIFT 24
+#define R128_PRIM_TEXTURE_BORDER_COLOR_C 0x1d38
+# define R128_PRIM_TEX_BORDER_BLUE_SHIFT 0
+# define R128_PRIM_TEX_BORDER_GREEN_SHIFT 8
+# define R128_PRIM_TEX_BORDER_RED_SHIFT 16
+# define R128_PRIM_TEX_BORDER_ALPHA_SHIFT 24
+#define R128_SEC_TEXTURE_BORDER_COLOR_C 0x1d3c
+# define R128_SEC_TEX_BORDER_BLUE_SHIFT 0
+# define R128_SEC_TEX_BORDER_GREEN_SHIFT 8
+# define R128_SEC_TEX_BORDER_RED_SHIFT 16
+# define R128_SEC_TEX_BORDER_ALPHA_SHIFT 24
+#define R128_STEN_REF_MASK_C 0x1d40
+# define R128_STEN_REFERENCE_SHIFT 0
+# define R128_STEN_MASK_SHIFT 16
+# define R128_STEN_WRITE_MASK_SHIFT 24
+#define R128_PLANE_3D_MASK_C 0x1d44
+
+
+ /* Constants */
+#define R128_AGP_TEX_OFFSET 0x02000000
+
+#define R128_VB_AGE_REG R128_GUI_SCRATCH_REG0
+#define R128_SWAP_AGE_REG R128_GUI_SCRATCH_REG1
+
+ /* CCE packet types */
+#define R128_CCE_PACKET0 0x00000000
+#define R128_CCE_PACKET0_ONE_REG_WR 0x00008000
+#define R128_CCE_PACKET1 0x40000000
+#define R128_CCE_PACKET2 0x80000000
+#define R128_CCE_PACKET3_NOP 0xC0001000
+#define R128_CCE_PACKET3_PAINT 0xC0001100
+#define R128_CCE_PACKET3_BITBLT 0xC0001200
+#define R128_CCE_PACKET3_SMALLTEXT 0xC0001300
+#define R128_CCE_PACKET3_HOSTDATA_BLT 0xC0001400
+#define R128_CCE_PACKET3_POLYLINE 0xC0001500
+#define R128_CCE_PACKET3_SCALING 0xC0001600
+#define R128_CCE_PACKET3_TRANS_SCALING 0xC0001700
+#define R128_CCE_PACKET3_POLYSCANLINES 0xC0001800
+#define R128_CCE_PACKET3_NEXT_CHAR 0xC0001900
+#define R128_CCE_PACKET3_PAINT_MULTI 0xC0001A00
+#define R128_CCE_PACKET3_BITBLT_MULTI 0xC0001B00
+#define R128_CCE_PACKET3_PLY_NEXTSCAN 0xC0001D00
+#define R128_CCE_PACKET3_SET_SCISSORS 0xC0001E00
+#define R128_CCE_PACKET3_SET_MODE24BPP 0xC0001F00
+#define R128_CCE_PACKET3_CNTL_PAINT 0xC0009100
+#define R128_CCE_PACKET3_CNTL_BITBLT 0xC0009200
+#define R128_CCE_PACKET3_CNTL_SMALLTEXT 0xC0009300
+#define R128_CCE_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400
+#define R128_CCE_PACKET3_CNTL_POLYLINE 0xC0009500
+#define R128_CCE_PACKET3_CNTL_SCALING 0xC0009600
+#define R128_CCE_PACKET3_CNTL_TRANS_SCALING 0xC0009700
+#define R128_CCE_PACKET3_CNTL_POLYSCANLINES 0xC0009800
+#define R128_CCE_PACKET3_CNTL_NEXT_CHAR 0xC0009900
+#define R128_CCE_PACKET3_CNTL_PAINT_MULTI 0xC0009A00
+#define R128_CCE_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00
+#define R128_CCE_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00
+#define R128_CCE_PACKET3_3D_SAVE_CONTEXT 0xC0002000
+#define R128_CCE_PACKET3_3D_PLAY_CONTEXT 0xC0002100
+#define R128_CCE_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300
+#define R128_CCE_PACKET3_3D_RNDR_GEN_PRIM 0xC0002500
+#define R128_CCE_PACKET3_LOAD_PALETTE 0xC0002C00
+#define R128_CCE_PACKET3_PURGE 0xC0002D00
+#define R128_CCE_PACKET3_NEXT_VERTEX_BUNDLE 0xC0002E00
+# define R128_CCE_PACKET_MASK 0xC0000000
+# define R128_CCE_PACKET_COUNT_MASK 0x3fff0000
+# define R128_CCE_PACKET_MAX_DWORDS (1 << 14)
+# define R128_CCE_PACKET0_REG_MASK 0x000007ff
+# define R128_CCE_PACKET1_REG0_MASK 0x000007ff
+# define R128_CCE_PACKET1_REG1_MASK 0x003ff800
+
+#define R128_CCE_VC_FRMT_RHW 0x00000001
+#define R128_CCE_VC_FRMT_DIFFUSE_BGR 0x00000002
+#define R128_CCE_VC_FRMT_DIFFUSE_A 0x00000004
+#define R128_CCE_VC_FRMT_DIFFUSE_ARGB 0x00000008
+#define R128_CCE_VC_FRMT_SPEC_BGR 0x00000010
+#define R128_CCE_VC_FRMT_SPEC_F 0x00000020
+#define R128_CCE_VC_FRMT_SPEC_FRGB 0x00000040
+#define R128_CCE_VC_FRMT_S_T 0x00000080
+#define R128_CCE_VC_FRMT_S2_T2 0x00000100
+#define R128_CCE_VC_FRMT_RHW2 0x00000200
+
+#define R128_CCE_VC_CNTL_PRIM_TYPE_NONE 0x00000000
+#define R128_CCE_VC_CNTL_PRIM_TYPE_POINT 0x00000001
+#define R128_CCE_VC_CNTL_PRIM_TYPE_LINE 0x00000002
+#define R128_CCE_VC_CNTL_PRIM_TYPE_POLY_LINE 0x00000003
+#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004
+#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005
+#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006
+#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 0x00000007
+#define R128_CCE_VC_CNTL_PRIM_WALK_IND 0x00000010
+#define R128_CCE_VC_CNTL_PRIM_WALK_LIST 0x00000020
+#define R128_CCE_VC_CNTL_PRIM_WALK_RING 0x00000030
+#define R128_CCE_VC_CNTL_NUM_SHIFT 16
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_sarea.h b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_sarea.h
new file mode 100644
index 000000000..c5d99df34
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_sarea.h
@@ -0,0 +1,77 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_SAREA_H_
+#define _R128_SAREA_H_
+
+/* There are 2 heaps (local/AGP). Each region within a heap is a
+ minimum of 64k, and there are at most 64 of them per heap. */
+#define R128_LOCAL_TEX_HEAP 0
+#define R128_AGP_TEX_HEAP 1
+#define R128_NR_TEX_HEAPS 2
+#define R128_NR_TEX_REGIONS 64
+#define R128_LOG_TEX_GRANULARITY 16
+
+typedef struct {
+ unsigned char next, prev; /* indices to form a circular LRU */
+ unsigned char in_use; /* owned by a client, or free? */
+ int age; /* tracked by clients to update local LRU's */
+} R128TexRegion;
+
+typedef struct {
+ /* Maintain an LRU of contiguous regions of texture space. If you
+ * think you own a region of texture memory, and it has an age
+ * different to the one you set, then you are mistaken and it has
+ * been stolen by another client. If global texAge hasn't changed,
+ * there is no need to walk the list.
+ *
+ * These regions can be used as a proxy for the fine-grained texture
+ * information of other clients - by maintaining them in the same
+ * lru which is used to age their own textures, clients have an
+ * approximate lru for the whole of global texture space, and can
+ * make informed decisions as to which areas to kick out. There is
+ * no need to choose whether to kick out your own texture or someone
+ * else's - simply eject them all in LRU order.
+ */
+ /* Last elt is sentinal */
+ R128TexRegion texList[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1];
+ /* last time texture was uploaded */
+ int texAge[R128_NR_TEX_HEAPS];
+
+ int ctxOwner; /* last context to upload state */
+
+ int ringWrite; /* current ring buffer write index */
+} R128SAREAPriv, *R128SAREAPrivPtr;
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/loader/xf86sym.c b/xc/programs/Xserver/hw/xfree86/loader/xf86sym.c
index 3d21e1c87..9844d6d90 100644
--- a/xc/programs/Xserver/hw/xfree86/loader/xf86sym.c
+++ b/xc/programs/Xserver/hw/xfree86/loader/xf86sym.c
@@ -54,6 +54,12 @@
#include "xf86Priv.h"
#include "vbe.h"
+#ifdef __FreeBSD__
+/* XXX used in drmOpen(). This should change to use a less os-specific
+ * method. */
+int sysctlbyname(const char*, void *, size_t *, void *, size_t);
+#endif
+
extern xf86MonPtr ConfiguredMonitor;
/* XXX Should get all of these from elsewhere */
@@ -894,6 +900,10 @@ LOOKUP xfree86LookupTab[] = {
#endif
#endif
+#ifdef __FreeBSD__
+ SYMFUNC(sysctlbyname)
+#endif
+
/*
* and now some variables
*/
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/Imakefile
index 7041d435a..c42f5b2b7 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/Imakefile
+++ b/xc/programs/Xserver/hw/xfree86/os-support/Imakefile
@@ -100,6 +100,7 @@ OS_SUBDIR = sco
#if BuildXF86DRI && !DoLoadableServer
DRM_SRC = $(OS_SUBDIR)/drm/?*.c
DRM_OBJ = $(OS_SUBDIR)/drm/?*.o
+DRM_DONES = $(OS_SUBDIR)/drm/DONE
#endif
SUBDIRS = $(OS_SUBDIR) $(BUS_SUBDIR) misc vbe
@@ -107,7 +108,7 @@ SUBDIRS = $(OS_SUBDIR) $(BUS_SUBDIR) misc vbe
SRCS = $(OS_SUBDIR)/?*.c $(BUS_SUBDIR)/?*.c misc/?*.c vbe/?*.c $(DRM_SRC)
OBJS = $(OS_SUBDIR)/?*.o $(BUS_SUBDIR)/?*.o misc/?*.o vbe/?*.o $(DRM_OBJ)
-DONES = $(OS_SUBDIR)/DONE $(BUS_SUBDIR)/DONE misc/DONE vbe/DONE
+DONES = $(OS_SUBDIR)/DONE $(BUS_SUBDIR)/DONE misc/DONE vbe/DONE $(DRM_DONES)
#if HasParallelMake
MakeMutex($(SUBDIRS) $(OBJS) $(DONES))
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/bsd/Imakefile
index b0ec00a5e..81f28bea8 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/bsd/Imakefile
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/Imakefile
@@ -43,6 +43,11 @@ IOPERM_OBJ = ioperm_noop.o
# endif
#endif
+#if BuildXF86DRI
+DRI_SRC = sigio.c
+DRI_OBJ = sigio.o
+#endif
+
MOUSESRC = bsd_mouse.c
MOUSEOBJ = bsd_mouse.o
@@ -84,12 +89,12 @@ AXP_OBJ=bsd_ev56.o
SRCS = bsd_init.c bsd_video.c bsd_io.c bsd_VTsw.c \
libc_wrapper.c $(IOPERM_SRC) std_kbdEv.c posix_tty.c $(MOUSESRC) \
$(RES_SRC) stdPci.c vidmem.c $(JOYSTICK_SRC) sigio.c $(APMSRC) \
- $(AXP_SRC)
+ $(AXP_SRC) kmod_noop.c
OBJS = bsd_init.o bsd_video.o bsd_io.o bsd_VTsw.o \
libc_wrapper.o $(IOPERM_OBJ) std_kbdEv.o posix_tty.o $(MOUSEOBJ) \
$(RES_OBJ) stdPci.o vidmem.o $(JOYSTICK_OBJ) sigio.o $(APMOBJ) \
- $(AXP_OBJ)
+ $(AXP_OBJ) kmod_noop.o
INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
-I$(XINCLUDESRC) -I$(EXTINCSRC) -I$(SERVERSRC)/mi -I$(APINCLUDES) \
@@ -114,6 +119,14 @@ SpecialObjectRule(bsd_ev56.o, bsd_ev56.c, -mcpu=ev56)
SubdirLibraryRule($(OBJS))
NormalLibraryObjectRule()
+#if BuildXF86DRI
+#define IHaveSubdirs
+SUBDIRS = drm
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
+
#if BuildXInputExt
# if DoLoadableServer
# if JoystickSupport
@@ -136,6 +149,7 @@ LinkSourceFile(stdResource.c,../shared)
LinkSourceFile(stdPci.c,../shared)
LinkSourceFile(vidmem.c,../shared)
LinkSourceFile(sigio.c,../shared)
+LinkSourceFile(kmod_noop.c,../shared)
DependTarget()
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/Imakefile
new file mode 100644
index 000000000..4639b530d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/Imakefile
@@ -0,0 +1,41 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile,v 1.4 1999/09/25 14:37:49 dawes Exp $
+XCOMM $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile,v 1.7 1999/09/14 19:55:15 faith Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#if DoLoadableServer
+MSRC = drmmodule.c
+MOBJ = drmmodule.o
+#endif
+
+#if BuildXF86DRI
+#if HasMTRRSupport
+MTRR_DEFINES = -DHAS_MTRR_SUPPORT
+#endif
+
+SRCS = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c xf86drmI810.c xf86drmMga.c xf86drmR128.c $(MSRC)
+OBJS = xf86drm.o xf86drmHash.o xf86drmRandom.o xf86drmSL.o xf86drmI810.o xf86drmMga.o xf86drmR128.o $(MOBJ)
+
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC) -I$(EXTINCSRC) -I../.. -Ikernel
+
+DEFINES = $(MTRR_DEFINES) $(GLX_DEFINES)
+
+ModuleObjectRule()
+LibraryModuleTarget(drm,$(OBJS))
+NormalLintTarget($(SRCS))
+
+InstallLibraryModule(drm,$(MODULEDIR),freebsd)
+
+#define IHaveSubdirs
+SUBDIRS = kernel
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
+
+
+
+InstallDriverSDKLibraryModule(drm,$(DRIVERSDKMODULEDIR),freebsd)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/drmmodule.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/drmmodule.c
new file mode 100644
index 000000000..1ddf3f4c1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/drmmodule.c
@@ -0,0 +1,56 @@
+/* drmmodule.c -- Module initialization
+ * Created: Fri Jun 4 09:05:48 1999 by faith@precisioninsight.com
+ * Revised: Fri Jun 4 09:09:22 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/drmmodule.c,v 1.1 1999/06/07 13:01:42 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/drmmodule.c,v 1.1 1999/06/14 07:32:01 dawes Exp $
+ *
+ */
+
+#include "xf86Module.h"
+
+static MODULESETUPPROTO(drmSetup);
+
+static XF86ModuleVersionInfo VersRec =
+{
+ "drm",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_EXTENSION,
+ ABI_EXTENSION_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0}
+};
+
+XF86ModuleData drmModuleData = { &VersRec, drmSetup, NULL };
+
+static pointer
+drmSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ return (void *)1;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/Imakefile
new file mode 100644
index 000000000..cf042d218
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/Imakefile
@@ -0,0 +1,31 @@
+XCOMM $XFree86$
+XCOMM $PI$
+
+#include <Server.tmpl>
+
+LinkSourceFile(xf86drm.c,..)
+LinkSourceFile(xf86drmHash.c,..)
+LinkSourceFile(xf86drmRandom.c,..)
+LinkSourceFile(xf86drmSL.c,..)
+LinkSourceFile(xf86drm.h,$(XF86OSSRC))
+LinkSourceFile(xf86_OSproc.h,$(XF86OSSRC))
+LinkSourceFile(sigio.c,$(XF86OSSRC)/shared)
+
+XCOMM This is a kludge until we determine how best to build the
+XCOMM kernel-specific device driver. This allows us to continue
+XCOMM to maintain the single Makefile.bsd with kernel-specific
+XCOMM support. Later, we can move to a different Imakefile.
+
+#if BuildXF86DRI && BuildXF86DRM
+all::
+ $(MAKE) -f Makefile.bsd
+
+install::
+ $(MAKE) -f Makefile.bsd install
+#else
+all::
+ echo 'Use "make -f Makefile.bsd" to manually build drm.o'
+#endif
+
+clean::
+ $(MAKE) -f Makefile.bsd clean
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/Makefile.bsd b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/Makefile.bsd
new file mode 100644
index 000000000..ff26c7628
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/Makefile.bsd
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SUBDIR = drm tdfx gamma
+
+.include <bsd.subdir.mk>
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm.h
new file mode 100644
index 000000000..9e0ade357
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm.h
@@ -0,0 +1,359 @@
+/* drm.h -- Header for Direct Rendering Manager -*- c -*-
+ * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
+ * Revised: Fri Aug 20 13:08:18 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h,v 1.46 1999/08/20 20:00:53 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h,v 1.1 1999/09/25 14:37:58 dawes Exp $
+ *
+ */
+
+#ifndef _DRM_H_
+#define _DRM_H_
+
+#include <sys/ioccom.h> /* For _IO* macros */
+
+#define DRM_DEV_DRM "/dev/drm"
+#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
+#define DRM_DEV_UID 0
+#define DRM_DEV_GID 0
+
+
+#define DRM_NAME "drm" /* Name in kernel, /dev */
+#define DRM_MIN_ORDER 5 /* At least 2^5 bytes = 32 bytes */
+#define DRM_MAX_ORDER 22 /* Up to 2^22 bytes = 4MB */
+#define DRM_RAM_PERCENT 10 /* How much system ram can we lock? */
+
+#define _DRM_LOCK_HELD 0x80000000 /* Hardware lock is held */
+#define _DRM_LOCK_CONT 0x40000000 /* Hardware lock is contended */
+#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD)
+#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT)
+#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
+
+typedef unsigned long drm_handle_t;
+typedef unsigned int drm_context_t;
+typedef unsigned int drm_drawable_t;
+typedef unsigned int drm_magic_t;
+
+/* Warning: If you change this structure, make sure you change
+ * XF86DRIClipRectRec in the server as well */
+
+typedef struct drm_clip_rect {
+ unsigned short x1;
+ unsigned short y1;
+ unsigned short x2;
+ unsigned short y2;
+} drm_clip_rect_t;
+
+/* Seperate include files for the i810/mga specific structures */
+#include "mga_drm.h"
+#include "i810_drm.h"
+#include "r128_drm.h"
+
+typedef struct drm_version {
+ int version_major; /* Major version */
+ int version_minor; /* Minor version */
+ int version_patchlevel;/* Patch level */
+ size_t name_len; /* Length of name buffer */
+ char *name; /* Name of driver */
+ size_t date_len; /* Length of date buffer */
+ char *date; /* User-space buffer to hold date */
+ size_t desc_len; /* Length of desc buffer */
+ char *desc; /* User-space buffer to hold desc */
+} drm_version_t;
+
+typedef struct drm_unique {
+ size_t unique_len; /* Length of unique */
+ char *unique; /* Unique name for driver instantiation */
+} drm_unique_t;
+
+typedef struct drm_list {
+ int count; /* Length of user-space structures */
+ drm_version_t *version;
+} drm_list_t;
+
+typedef struct drm_block {
+ int unused;
+} drm_block_t;
+
+typedef struct drm_control {
+ enum {
+ DRM_ADD_COMMAND,
+ DRM_RM_COMMAND,
+ DRM_INST_HANDLER,
+ DRM_UNINST_HANDLER
+ } func;
+ int irq;
+} drm_control_t;
+
+typedef enum drm_map_type {
+ _DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
+ _DRM_REGISTERS = 1, /* no caching, no core dump */
+ _DRM_SHM = 2, /* shared, cached */
+ _DRM_AGP = 3 /* AGP/GART */
+} drm_map_type_t;
+
+typedef enum drm_map_flags {
+ _DRM_RESTRICTED = 0x01, /* Cannot be mapped to user-virtual */
+ _DRM_READ_ONLY = 0x02,
+ _DRM_LOCKED = 0x04, /* shared, cached, locked */
+ _DRM_KERNEL = 0x08, /* kernel requires access */
+ _DRM_WRITE_COMBINING = 0x10, /* use write-combining if available */
+ _DRM_CONTAINS_LOCK = 0x20 /* SHM page that contains lock */
+} drm_map_flags_t;
+
+typedef struct drm_map {
+ unsigned long offset; /* Requested physical address (0 for SAREA)*/
+ unsigned long size; /* Requested physical size (bytes) */
+ drm_map_type_t type; /* Type of memory to map */
+ drm_map_flags_t flags; /* Flags */
+ void *handle; /* User-space: "Handle" to pass to mmap */
+ /* Kernel-space: kernel-virtual address */
+ int mtrr; /* MTRR slot used */
+ /* Private data */
+} drm_map_t;
+
+typedef enum drm_lock_flags {
+ _DRM_LOCK_READY = 0x01, /* Wait until hardware is ready for DMA */
+ _DRM_LOCK_QUIESCENT = 0x02, /* Wait until hardware quiescent */
+ _DRM_LOCK_FLUSH = 0x04, /* Flush this context's DMA queue first */
+ _DRM_LOCK_FLUSH_ALL = 0x08, /* Flush all DMA queues first */
+ /* These *HALT* flags aren't supported yet
+ -- they will be used to support the
+ full-screen DGA-like mode. */
+ _DRM_HALT_ALL_QUEUES = 0x10, /* Halt all current and future queues */
+ _DRM_HALT_CUR_QUEUES = 0x20 /* Halt all current queues */
+} drm_lock_flags_t;
+
+typedef struct drm_lock {
+ int context;
+ drm_lock_flags_t flags;
+} drm_lock_t;
+
+typedef enum drm_dma_flags { /* These values *MUST* match xf86drm.h */
+ /* Flags for DMA buffer dispatch */
+ _DRM_DMA_BLOCK = 0x01, /* Block until buffer dispatched.
+ Note, the buffer may not yet have
+ been processed by the hardware --
+ getting a hardware lock with the
+ hardware quiescent will ensure
+ that the buffer has been
+ processed. */
+ _DRM_DMA_WHILE_LOCKED = 0x02, /* Dispatch while lock held */
+ _DRM_DMA_PRIORITY = 0x04, /* High priority dispatch */
+
+ /* Flags for DMA buffer request */
+ _DRM_DMA_WAIT = 0x10, /* Wait for free buffers */
+ _DRM_DMA_SMALLER_OK = 0x20, /* Smaller-than-requested buffers ok */
+ _DRM_DMA_LARGER_OK = 0x40 /* Larger-than-requested buffers ok */
+} drm_dma_flags_t;
+
+typedef struct drm_buf_desc {
+ int count; /* Number of buffers of this size */
+ int size; /* Size in bytes */
+ int low_mark; /* Low water mark */
+ int high_mark; /* High water mark */
+ enum {
+ _DRM_PAGE_ALIGN = 0x01, /* Align on page boundaries for DMA */
+ _DRM_AGP_BUFFER = 0x02 /* Buffer is in agp space */
+ } flags;
+ unsigned long agp_start; /* Start address of where the agp buffers
+ * are in the agp aperture */
+} drm_buf_desc_t;
+
+typedef struct drm_buf_info {
+ int count; /* Entries in list */
+ drm_buf_desc_t *list;
+} drm_buf_info_t;
+
+typedef struct drm_buf_free {
+ int count;
+ int *list;
+} drm_buf_free_t;
+
+typedef struct drm_buf_pub {
+ int idx; /* Index into master buflist */
+ int total; /* Buffer size */
+ int used; /* Amount of buffer in use (for DMA) */
+ void *address; /* Address of buffer */
+} drm_buf_pub_t;
+
+typedef struct drm_buf_map {
+ int count; /* Length of buflist */
+ void *virtual; /* Mmaped area in user-virtual */
+ drm_buf_pub_t *list; /* Buffer information */
+} drm_buf_map_t;
+
+typedef struct drm_dma {
+ /* Indices here refer to the offset into
+ buflist in drm_buf_get_t. */
+ int context; /* Context handle */
+ int send_count; /* Number of buffers to send */
+ int *send_indices; /* List of handles to buffers */
+ int *send_sizes; /* Lengths of data to send */
+ drm_dma_flags_t flags; /* Flags */
+ int request_count; /* Number of buffers requested */
+ int request_size; /* Desired size for buffers */
+ int *request_indices; /* Buffer information */
+ int *request_sizes;
+ int granted_count; /* Number of buffers granted */
+} drm_dma_t;
+
+typedef enum {
+ _DRM_CONTEXT_PRESERVED = 0x01,
+ _DRM_CONTEXT_2DONLY = 0x02
+} drm_ctx_flags_t;
+
+typedef struct drm_ctx {
+ drm_context_t handle;
+ drm_ctx_flags_t flags;
+} drm_ctx_t;
+
+typedef struct drm_ctx_res {
+ int count;
+ drm_ctx_t *contexts;
+} drm_ctx_res_t;
+
+typedef struct drm_draw {
+ drm_drawable_t handle;
+} drm_draw_t;
+
+typedef struct drm_auth {
+ drm_magic_t magic;
+} drm_auth_t;
+
+typedef struct drm_irq_busid {
+ int irq;
+ int busnum;
+ int devnum;
+ int funcnum;
+} drm_irq_busid_t;
+
+typedef struct drm_agp_mode {
+ unsigned long mode;
+} drm_agp_mode_t;
+
+ /* For drm_agp_alloc -- allocated a buffer */
+typedef struct drm_agp_buffer {
+ unsigned long size; /* In bytes -- will round to page boundary */
+ unsigned long handle; /* Used for BIND/UNBIND ioctls */
+ unsigned long type; /* Type of memory to allocate */
+ unsigned long physical; /* Physical used by i810 */
+} drm_agp_buffer_t;
+
+ /* For drm_agp_bind */
+typedef struct drm_agp_binding {
+ unsigned long handle; /* From drm_agp_buffer */
+ unsigned long offset; /* In bytes -- will round to page boundary */
+} drm_agp_binding_t;
+
+typedef struct drm_agp_info {
+ int agp_version_major;
+ int agp_version_minor;
+ unsigned long mode;
+ unsigned long aperture_base; /* physical address */
+ unsigned long aperture_size; /* bytes */
+ unsigned long memory_allowed; /* bytes */
+ unsigned long memory_used;
+
+ /* PCI information */
+ unsigned short id_vendor;
+ unsigned short id_device;
+} drm_agp_info_t;
+
+#define DRM_IOCTL_BASE 'd'
+#define DRM_IOCTL_NR(n) ((n) & 0xff)
+#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
+#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size)
+#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size)
+#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size)
+
+
+#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t)
+#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t)
+#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t)
+#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t)
+
+#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t)
+#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t)
+#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, drm_block_t)
+#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, drm_block_t)
+#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, drm_control_t)
+#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, drm_map_t)
+#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, drm_buf_desc_t)
+#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, drm_buf_desc_t)
+#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm_buf_info_t)
+#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t)
+#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t)
+
+#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t)
+#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t)
+#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t)
+#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, drm_ctx_t)
+#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, drm_ctx_t)
+#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, drm_ctx_t)
+#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t)
+#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, drm_draw_t)
+#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, drm_draw_t)
+#define DRM_IOCTL_DMA DRM_IOWR(0x29, drm_dma_t)
+#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, drm_lock_t)
+#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t)
+#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t)
+
+#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
+#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
+#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t)
+#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t)
+#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t)
+#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t)
+#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
+#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
+
+/* Mga specific ioctls */
+#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
+#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t)
+#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t)
+#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t)
+#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t)
+#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t )
+#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
+
+/* I810 specific ioctls */
+#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
+#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
+#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t)
+#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43)
+#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44)
+#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
+#define DRM_IOCTL_I810_SWAP DRM_IO ( 0x46)
+
+/* Rage 128 specific ioctls */
+#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
+#define DRM_IOCTL_R128_RESET DRM_IO( 0x41)
+#define DRM_IOCTL_R128_FLUSH DRM_IO( 0x42)
+#define DRM_IOCTL_R128_CCEIDL DRM_IO( 0x43)
+#define DRM_IOCTL_R128_PACKET DRM_IOW( 0x44, drm_r128_packet_t)
+#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x45, drm_r128_vertex_t)
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/Makefile b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/Makefile
new file mode 100644
index 000000000..6a70a5b0f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/Makefile
@@ -0,0 +1,17 @@
+# $FreeBSD$
+
+KMOD = drm
+SRCS = init.c memory.c auth.c context.c drawable.c bufs.c \
+ lists.c lock.c ioctl.c fops.c vm.c dma.c sysctl.c \
+ agpsupport.c
+SRCS += device_if.h bus_if.h pci_if.h
+CFLAGS += ${DEBUG_FLAGS} -I.. # -DDRM_AGP
+KERN = /usr/src/sys
+
+@:
+ ln -sf /sys @
+
+machine:
+ ln -sf /sys/i386/include machine
+
+.include "/usr/src/sys/conf/kmod.mk"
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/agpsupport.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/agpsupport.c
new file mode 100644
index 000000000..53444c907
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/agpsupport.c
@@ -0,0 +1,271 @@
+/* agpsupport.c -- DRM support for AGP/GART backend
+ * Created: Mon Dec 13 09:56:45 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Rickard E. (Rik) Faith <faith@precisioninsight.com>
+ *
+ * $XFree86$
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+#ifdef DRM_AGP
+
+#include <pci/agpvar.h>
+
+MODULE_DEPEND(drm, agp, 1, 1, 1);
+
+int
+drm_agp_info(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ struct agp_info *kern;
+ drm_agp_info_t info;
+
+ if (!dev->agp->acquired) return EINVAL;
+
+ kern = &dev->agp->info;
+ agp_get_info(dev->agp->agpdev, kern);
+ info.agp_version_major = 1;
+ info.agp_version_minor = 0;
+ info.mode = kern->ai_mode;
+ info.aperture_base = kern->ai_aperture_base;
+ info.aperture_size = kern->ai_aperture_size;
+ info.memory_allowed = kern->ai_memory_allowed;
+ info.memory_used = kern->ai_memory_used;
+ info.id_vendor = kern->ai_devid & 0xffff;
+ info.id_device = kern->ai_devid >> 16;
+
+ *(drm_agp_info_t *) data = info;
+ return 0;
+}
+
+int
+drm_agp_acquire(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ int retcode;
+
+ if (dev->agp->acquired) return EINVAL;
+ retcode = agp_acquire(dev->agp->agpdev);
+ if (retcode) return retcode;
+ dev->agp->acquired = 1;
+ return 0;
+}
+
+int
+drm_agp_release(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+
+ if (!dev->agp->acquired) return EINVAL;
+ agp_release(dev->agp->agpdev);
+ dev->agp->acquired = 0;
+ return 0;
+
+}
+
+int
+drm_agp_enable(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_agp_mode_t mode;
+
+ if (!dev->agp->acquired) return EINVAL;
+
+ mode = *(drm_agp_mode_t *) data;
+
+ dev->agp->mode = mode.mode;
+ agp_enable(dev->agp->agpdev, mode.mode);
+ dev->agp->base = dev->agp->info.ai_aperture_base;
+ dev->agp->enabled = 1;
+ return 0;
+}
+
+int drm_agp_alloc(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_agp_buffer_t request;
+ drm_agp_mem_t *entry;
+ void *handle;
+ unsigned long pages;
+ u_int32_t type;
+ struct agp_memory_info info;
+
+ if (!dev->agp->acquired) return EINVAL;
+
+ request = *(drm_agp_buffer_t *) data;
+
+ if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS)))
+ return ENOMEM;
+
+ memset(entry, 0, sizeof(*entry));
+
+ pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
+ type = (u_int32_t) request.type;
+
+ if (!(handle = drm_alloc_agp(pages, type))) {
+ drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+ return ENOMEM;
+ }
+
+ entry->handle = handle;
+ entry->bound = 0;
+ entry->pages = pages;
+ entry->prev = NULL;
+ entry->next = dev->agp->memory;
+ if (dev->agp->memory) dev->agp->memory->prev = entry;
+ dev->agp->memory = entry;
+
+ agp_memory_info(dev->agp->agpdev, entry->handle, &info);
+
+ request.handle = (unsigned long) entry->handle;
+ request.physical = info.ami_physical;
+
+ *(drm_agp_buffer_t *) data = request;
+
+ return 0;
+}
+
+static drm_agp_mem_t *
+drm_agp_lookup_entry(drm_device_t *dev, void *handle)
+{
+ drm_agp_mem_t *entry;
+
+ for (entry = dev->agp->memory; entry; entry = entry->next) {
+ if (entry->handle == handle) return entry;
+ }
+ return NULL;
+}
+
+int
+drm_agp_unbind(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_agp_binding_t request;
+ drm_agp_mem_t *entry;
+
+ if (!dev->agp->acquired) return EINVAL;
+ request = *(drm_agp_binding_t *) data;
+ if (!(entry = drm_agp_lookup_entry(dev, (void *) request.handle)))
+ return EINVAL;
+ if (!entry->bound) return EINVAL;
+ return drm_unbind_agp(entry->handle);
+}
+
+int drm_agp_bind(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_agp_binding_t request;
+ drm_agp_mem_t *entry;
+ int retcode;
+ int page;
+
+ if (!dev->agp->acquired) return EINVAL;
+ request = *(drm_agp_binding_t *) data;
+ if (!(entry = drm_agp_lookup_entry(dev, (void *) request.handle)))
+ return EINVAL;
+ if (entry->bound) return EINVAL;
+ page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
+ if ((retcode = drm_bind_agp(entry->handle, page))) return retcode;
+ entry->bound = dev->agp->base + (page << PAGE_SHIFT);
+ return 0;
+}
+
+int drm_agp_free(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_agp_buffer_t request;
+ drm_agp_mem_t *entry;
+
+ if (!dev->agp->acquired) return EINVAL;
+ request = *(drm_agp_buffer_t *) data;
+ if (!(entry = drm_agp_lookup_entry(dev, (void*) request.handle)))
+ return EINVAL;
+ if (entry->bound) drm_unbind_agp(entry->handle);
+
+ if (entry->prev) entry->prev->next = entry->next;
+ else dev->agp->memory = entry->next;
+ if (entry->next) entry->next->prev = entry->prev;
+ drm_free_agp(entry->handle, entry->pages);
+ drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+ return 0;
+}
+
+drm_agp_head_t *drm_agp_init(void)
+{
+ device_t agpdev;
+ drm_agp_head_t *head = NULL;
+ int agp_available = 1;
+
+ agpdev = agp_find_device();
+ if (!agpdev)
+ agp_available = 0;
+
+ DRM_DEBUG("agp_available = %d\n", agp_available);
+
+ if (agp_available) {
+ if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
+ return NULL;
+ head->agpdev = agpdev;
+ memset((void *)head, 0, sizeof(*head));
+ agp_get_info(agpdev, &head->info);
+ head->memory = NULL;
+#if 0 /* bogus */
+ switch (head->agp_info.chipset) {
+ case INTEL_GENERIC: head->chipset = "Intel"; break;
+ case INTEL_LX: head->chipset = "Intel 440LX"; break;
+ case INTEL_BX: head->chipset = "Intel 440BX"; break;
+ case INTEL_GX: head->chipset = "Intel 440GX"; break;
+ case INTEL_I810: head->chipset = "Intel i810"; break;
+ case VIA_GENERIC: head->chipset = "VIA"; break;
+ case VIA_VP3: head->chipset = "VIA VP3"; break;
+ case VIA_MVP3: head->chipset = "VIA MVP3"; break;
+ case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; break;
+ case SIS_GENERIC: head->chipset = "SiS"; break;
+ case AMD_GENERIC: head->chipset = "AMD"; break;
+ case AMD_IRONGATE: head->chipset = "AMD Irongate"; break;
+ case ALI_GENERIC: head->chipset = "ALi"; break;
+ case ALI_M1541: head->chipset = "ALi M1541"; break;
+ default:
+ }
+#endif
+ DRM_INFO("AGP at 0x%08x %dMB\n",
+ head->info.ai_aperture_base,
+ head->info.ai_aperture_size >> 20);
+ }
+ return head;
+}
+
+#endif /* DRM_AGP */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/auth.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/auth.c
new file mode 100644
index 000000000..f7b3bc493
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/auth.c
@@ -0,0 +1,168 @@
+/* auth.c -- IOCTLs for authentication -*- c -*-
+ * Created: Tue Feb 2 08:37:54 1999 by faith@precisioninsight.com
+ * Revised: Fri Aug 20 11:31:48 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/auth.c,v 1.4 1999/08/30 13:05:00 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/auth.c,v 1.1 1999/09/25 14:37:57 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+static int drm_hash_magic(drm_magic_t magic)
+{
+ return magic & (DRM_HASH_SIZE-1);
+}
+
+static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
+{
+ drm_file_t *retval = NULL;
+ drm_magic_entry_t *pt;
+ int hash = drm_hash_magic(magic);
+
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc);
+ for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
+ if (pt->priv->authenticated) continue;
+ if (pt->magic == magic) {
+ retval = pt->priv;
+ break;
+ }
+ }
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+
+ return retval;
+}
+
+int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
+{
+ int hash;
+ drm_magic_entry_t *entry;
+
+ DRM_DEBUG("%d\n", magic);
+
+ hash = drm_hash_magic(magic);
+ entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
+ if (!entry) return ENOMEM;
+ entry->magic = magic;
+ entry->priv = priv;
+ entry->next = NULL;
+
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc);
+ if (dev->magiclist[hash].tail) {
+ dev->magiclist[hash].tail->next = entry;
+ dev->magiclist[hash].tail = entry;
+ } else {
+ dev->magiclist[hash].head = entry;
+ dev->magiclist[hash].tail = entry;
+ }
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+
+ return 0;
+}
+
+int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
+{
+ drm_magic_entry_t *prev = NULL;
+ drm_magic_entry_t *pt;
+ int hash;
+
+ DRM_DEBUG("%d\n", magic);
+ hash = drm_hash_magic(magic);
+
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc);
+ for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) {
+ if (pt->magic == magic) {
+ if (dev->magiclist[hash].head == pt) {
+ dev->magiclist[hash].head = pt->next;
+ }
+ if (dev->magiclist[hash].tail == pt) {
+ dev->magiclist[hash].tail = prev;
+ }
+ if (prev) {
+ prev->next = pt->next;
+ }
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+ return 0;
+ }
+ }
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+
+ drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
+
+ return EINVAL;
+}
+
+int drm_getmagic(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ static drm_magic_t sequence = 0;
+#if 0
+ static struct simplelock lock; /* XXX */
+#endif
+ drm_device_t *dev = kdev->si_drv1;
+ drm_file_t *priv;
+ drm_auth_t auth;
+
+ /* Find unique magic */
+ priv = drm_find_file_by_proc(dev, p);
+ if (!priv) {
+ DRM_DEBUG("can't find file structure\n");
+ return EINVAL;
+ }
+ if (priv->magic) {
+ auth.magic = priv->magic;
+ } else {
+ simple_lock(&lock);
+ do {
+ if (!sequence) ++sequence; /* reserve 0 */
+ auth.magic = sequence++;
+ } while (drm_find_file(dev, auth.magic));
+ simple_unlock(&lock);
+ priv->magic = auth.magic;
+ drm_add_magic(dev, priv, auth.magic);
+ }
+
+ DRM_DEBUG("%u\n", auth.magic);
+ *(drm_auth_t *) data = auth;
+ return 0;
+}
+
+int drm_authmagic(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_auth_t auth;
+ drm_file_t *file;
+
+ auth = *(drm_auth_t *) data;
+ DRM_DEBUG("%u\n", auth.magic);
+ if ((file = drm_find_file(dev, auth.magic))) {
+ file->authenticated = 1;
+ drm_remove_magic(dev, auth.magic);
+ return 0;
+ }
+ return EINVAL;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/bufs.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/bufs.c
new file mode 100644
index 000000000..fc08b69d2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/bufs.c
@@ -0,0 +1,500 @@
+/* bufs.c -- IOCTLs to manage buffers -*- c -*-
+ * Created: Tue Feb 2 08:37:54 1999 by faith@precisioninsight.com
+ * Revised: Fri Aug 20 22:48:10 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/bufs.c,v 1.8 1999/08/30 13:05:00 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/bufs.c,v 1.1 1999/09/25 14:37:57 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+#include <sys/mman.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_map.h>
+
+ /* Compute order. Can be made faster. */
+int drm_order(unsigned long size)
+{
+ int order;
+ unsigned long tmp;
+
+ for (order = 0, tmp = size; tmp >>= 1; ++order);
+ if (size & ~(1 << order)) ++order;
+ return order;
+}
+
+int drm_addmap(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_map_t *map;
+
+ if (!(dev->flags & (FREAD|FWRITE)))
+ return EACCES; /* Require read/write */
+
+ map = drm_alloc(sizeof(*map), DRM_MEM_MAPS);
+ if (!map) return ENOMEM;
+ *map = *(drm_map_t *) data;
+
+ DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n",
+ map->offset, map->size, map->type);
+ if ((map->offset & (PAGE_SIZE-1)) || (map->size & (PAGE_SIZE-1))) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ DRM_DEBUG("offset or size not page aligned\n");
+ return EINVAL;
+ }
+ map->mtrr = -1;
+ map->handle = 0;
+
+ switch (map->type) {
+ case _DRM_REGISTERS:
+ case _DRM_FRAME_BUFFER:
+ if (map->offset + map->size < map->offset
+ /* || map->offset < virt_to_phys(high_memory) */) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ DRM_DEBUG("bad frame buffer size\n");
+ return EINVAL;
+ }
+#ifdef CONFIG_MTRR
+ if (map->type == _DRM_FRAME_BUFFER
+ || (map->flags & _DRM_WRITE_COMBINING)) {
+ map->mtrr = mtrr_add(map->offset, map->size,
+ MTRR_TYPE_WRCOMB, 1);
+ }
+#endif
+ map->handle = drm_ioremap(map->offset, map->size);
+ break;
+
+
+ case _DRM_SHM:
+ DRM_DEBUG("%ld %d\n", map->size, drm_order(map->size));
+ map->handle = (void *)drm_alloc_pages(drm_order(map->size)
+ - PAGE_SHIFT,
+ DRM_MEM_SAREA);
+ if (!map->handle) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return ENOMEM;
+ }
+ map->offset = (unsigned long)map->handle;
+ if (map->flags & _DRM_CONTAINS_LOCK) {
+ dev->lock.hw_lock = map->handle; /* Pointer to lock */
+ }
+ break;
+#ifdef DRM_AGP
+ case _DRM_AGP:
+ map->offset = map->offset + dev->agp->base;
+ break;
+#endif
+ default:
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ DRM_DEBUG("bad type\n");
+ return EINVAL;
+ }
+
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc);
+ if (dev->maplist) {
+ ++dev->map_count;
+ dev->maplist = drm_realloc(dev->maplist,
+ (dev->map_count-1)
+ * sizeof(*dev->maplist),
+ dev->map_count
+ * sizeof(*dev->maplist),
+ DRM_MEM_MAPS);
+ } else {
+ dev->map_count = 1;
+ dev->maplist = drm_alloc(dev->map_count*sizeof(*dev->maplist),
+ DRM_MEM_MAPS);
+ }
+ dev->maplist[dev->map_count-1] = map;
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+
+ *(drm_map_t *) data = *map;
+ if (map->type != _DRM_SHM)
+ ((drm_map_t *)data)->handle = (void *) map->offset;
+
+ return 0;
+}
+
+int drm_addbufs(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_desc_t request;
+ int count;
+ int order;
+ int size;
+ int total;
+ int page_order;
+ drm_buf_entry_t *entry;
+ unsigned long page;
+ drm_buf_t *buf;
+ int alignment;
+ unsigned long offset;
+ int i;
+ int byte_count;
+ int page_count;
+
+ if (!dma) return EINVAL;
+
+ request = *(drm_buf_desc_t *) data;
+
+ count = request.count;
+ order = drm_order(request.size);
+ size = 1 << order;
+
+ DRM_DEBUG("count = %d, size = %d (%d), order = %d, queue_count = %d\n",
+ request.count, request.size, size, order, dev->queue_count);
+
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return EINVAL;
+ if (dev->queue_count) return EBUSY; /* Not while in use */
+
+ alignment = (request.flags & _DRM_PAGE_ALIGN) ? round_page(size) :size;
+ page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+ total = PAGE_SIZE << page_order;
+
+ simple_lock(&dev->count_lock);
+ if (dev->buf_use) {
+ simple_unlock(&dev->count_lock);
+ return EBUSY;
+ }
+ atomic_inc(&dev->buf_alloc);
+ simple_unlock(&dev->count_lock);
+
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc);
+ entry = &dma->bufs[order];
+ if (entry->buf_count) {
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+ atomic_dec(&dev->buf_alloc);
+ return ENOMEM; /* May only call once for each order */
+ }
+
+ entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
+ DRM_MEM_BUFS);
+ if (!entry->buflist) {
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+ atomic_dec(&dev->buf_alloc);
+ return ENOMEM;
+ }
+ memset(entry->buflist, 0, count * sizeof(*entry->buflist));
+
+ entry->seglist = drm_alloc(count * sizeof(*entry->seglist),
+ DRM_MEM_SEGS);
+ if (!entry->seglist) {
+ drm_free(entry->buflist,
+ count * sizeof(*entry->buflist),
+ DRM_MEM_BUFS);
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+ atomic_dec(&dev->buf_alloc);
+ return ENOMEM;
+ }
+ memset(entry->seglist, 0, count * sizeof(*entry->seglist));
+
+ dma->pagelist = drm_realloc(dma->pagelist,
+ dma->page_count * sizeof(*dma->pagelist),
+ (dma->page_count + (count << page_order))
+ * sizeof(*dma->pagelist),
+ DRM_MEM_PAGES);
+ DRM_DEBUG("pagelist: %d entries\n",
+ dma->page_count + (count << page_order));
+
+
+ entry->buf_size = size;
+ entry->page_order = page_order;
+ byte_count = 0;
+ page_count = 0;
+ while (entry->buf_count < count) {
+ if (!(page = drm_alloc_pages(page_order, DRM_MEM_DMA))) break;
+ entry->seglist[entry->seg_count++] = page;
+ for (i = 0; i < (1 << page_order); i++) {
+ DRM_DEBUG("page %d @ 0x%08lx\n",
+ dma->page_count + page_count,
+ page + PAGE_SIZE * i);
+ dma->pagelist[dma->page_count + page_count++]
+ = page + PAGE_SIZE * i;
+ }
+ for (offset = 0;
+ offset + size <= total && entry->buf_count < count;
+ offset += alignment, ++entry->buf_count) {
+ buf = &entry->buflist[entry->buf_count];
+ buf->idx = dma->buf_count + entry->buf_count;
+ buf->total = alignment;
+ buf->order = order;
+ buf->used = 0;
+ buf->offset = (dma->byte_count + byte_count + offset);
+ buf->address = (void *)(page + offset);
+ buf->next = NULL;
+ buf->waiting = 0;
+ buf->pending = 0;
+ buf->dma_wait = 0;
+ buf->pid = 0;
+#if DRM_DMA_HISTOGRAM
+ timespecclear(&buf->time_queued);
+ timespecclear(&buf->time_dispatched);
+ timespecclear(&buf->time_completed);
+ timespecclear(&buf->time_freed);
+#endif
+ DRM_DEBUG("buffer %d @ %p\n",
+ entry->buf_count, buf->address);
+ }
+ byte_count += PAGE_SIZE << page_order;
+ }
+
+ dma->buflist = drm_realloc(dma->buflist,
+ dma->buf_count * sizeof(*dma->buflist),
+ (dma->buf_count + entry->buf_count)
+ * sizeof(*dma->buflist),
+ DRM_MEM_BUFS);
+ for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++)
+ dma->buflist[i] = &entry->buflist[i - dma->buf_count];
+
+ dma->buf_count += entry->buf_count;
+ dma->seg_count += entry->seg_count;
+ dma->page_count += entry->seg_count << page_order;
+ dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
+
+ drm_freelist_create(&entry->freelist, entry->buf_count);
+ for (i = 0; i < entry->buf_count; i++) {
+ drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
+ }
+
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+
+ request.count = entry->buf_count;
+ request.size = size;
+
+ *(drm_buf_desc_t *) data = request;
+
+ atomic_dec(&dev->buf_alloc);
+ return 0;
+}
+
+int drm_infobufs(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_info_t request;
+ int i;
+ int count;
+
+ if (!dma) return EINVAL;
+
+ simple_lock(&dev->count_lock);
+ if (atomic_read(&dev->buf_alloc)) {
+ simple_unlock(&dev->count_lock);
+ return EBUSY;
+ }
+ ++dev->buf_use; /* Can't allocate more after this call */
+ simple_unlock(&dev->count_lock);
+
+ request = *(drm_buf_info_t *) data;
+
+ for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
+ if (dma->bufs[i].buf_count) ++count;
+ }
+
+ DRM_DEBUG("count = %d\n", count);
+
+ if (request.count >= count) {
+ for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
+ if (dma->bufs[i].buf_count) {
+ int error;
+ error = copyout(&dma->bufs[i].buf_count,
+ &request.list[count].count,
+ sizeof(dma->bufs[0]
+ .buf_count));
+ if (error) return error;
+ error = copyout(&dma->bufs[i].buf_size,
+ &request.list[count].size,
+ sizeof(dma->bufs[0].buf_size));
+ if (error) return error;
+ error = copyout(&dma->bufs[i]
+ .freelist.low_mark,
+ &request.list[count].low_mark,
+ sizeof(dma->bufs[0]
+ .freelist.low_mark));
+ if (error) return error;
+ error = copyout(&dma->bufs[i]
+ .freelist.high_mark,
+ &request.list[count].high_mark,
+ sizeof(dma->bufs[0]
+ .freelist.high_mark));
+ if (error) return error;
+ DRM_DEBUG("%d %d %d %d %d\n",
+ i,
+ dma->bufs[i].buf_count,
+ dma->bufs[i].buf_size,
+ dma->bufs[i].freelist.low_mark,
+ dma->bufs[i].freelist.high_mark);
+ ++count;
+ }
+ }
+ }
+ request.count = count;
+
+ *(drm_buf_info_t *) data = request;
+
+ return 0;
+}
+
+int drm_markbufs(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_desc_t request;
+ int order;
+ drm_buf_entry_t *entry;
+
+ if (!dma) return EINVAL;
+
+ request = *(drm_buf_desc_t *) data;
+
+ DRM_DEBUG("%d, %d, %d\n",
+ request.size, request.low_mark, request.high_mark);
+ order = drm_order(request.size);
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return EINVAL;
+ entry = &dma->bufs[order];
+
+ if (request.low_mark < 0 || request.low_mark > entry->buf_count)
+ return EINVAL;
+ if (request.high_mark < 0 || request.high_mark > entry->buf_count)
+ return EINVAL;
+
+ entry->freelist.low_mark = request.low_mark;
+ entry->freelist.high_mark = request.high_mark;
+
+ return 0;
+}
+
+int drm_freebufs(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_free_t request;
+ int i;
+ int idx;
+ int error;
+ drm_buf_t *buf;
+
+ if (!dma) return EINVAL;
+
+ request = *(drm_buf_free_t *) data;
+
+ DRM_DEBUG("%d\n", request.count);
+ for (i = 0; i < request.count; i++) {
+ error = copyin(&request.list[i], &idx, sizeof(idx));
+ if (error)
+ return error;
+ if (idx < 0 || idx >= dma->buf_count) {
+ DRM_ERROR("Index %d (of %d max)\n",
+ idx, dma->buf_count - 1);
+ return EINVAL;
+ }
+ buf = dma->buflist[idx];
+ if (buf->pid != p->p_pid) {
+ DRM_ERROR("Process %d freeing buffer owned by %d\n",
+ p->p_pid, buf->pid);
+ return EINVAL;
+ }
+ drm_free_buffer(dev, buf);
+ }
+
+ return 0;
+}
+
+int drm_mapbufs(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_device_dma_t *dma = dev->dma;
+ int retcode = 0;
+ const int zero = 0;
+ vm_offset_t virtual;
+ vm_offset_t address;
+ drm_buf_map_t request;
+ int i;
+
+ if (!dma) return EINVAL;
+
+ DRM_DEBUG("\n");
+
+ simple_lock(&dev->count_lock);
+ if (atomic_read(&dev->buf_alloc)) {
+ simple_unlock(&dev->count_lock);
+ return EBUSY;
+ }
+ ++dev->buf_use; /* Can't allocate more after this call */
+ simple_unlock(&dev->count_lock);
+
+ request = *(drm_buf_map_t *) data;
+
+ if (request.count >= dma->buf_count) {
+ virtual = 0;
+ retcode = vm_mmap(&p->p_vmspace->vm_map,
+ &virtual,
+ round_page(dma->byte_count),
+ PROT_READ|PROT_WRITE, VM_PROT_ALL,
+ MAP_SHARED,
+ SLIST_FIRST(&kdev->si_hlist),
+ 0);
+ if (retcode)
+ goto done;
+
+ request.virtual = (void *)virtual;
+
+ for (i = 0; i < dma->buf_count; i++) {
+ retcode = copyout(&dma->buflist[i]->idx,
+ &request.list[i].idx,
+ sizeof(request.list[0].idx));
+ if (retcode) goto done;
+ retcode = copyout(&dma->buflist[i]->total,
+ &request.list[i].total,
+ sizeof(request.list[0].total));
+ if (retcode) goto done;
+ retcode = copyout(&zero,
+ &request.list[i].used,
+ sizeof(request.list[0].used));
+ if (retcode) goto done;
+ address = virtual + dma->buflist[i]->offset;
+ retcode = copyout(&address,
+ &request.list[i].address,
+ sizeof(address));
+ if (retcode) goto done;
+ }
+ }
+done:
+ request.count = dma->buf_count;
+ DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
+
+ *(drm_buf_map_t *) data = request;
+
+ return retcode;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/context.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/context.c
new file mode 100644
index 000000000..d79990f86
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/context.c
@@ -0,0 +1,297 @@
+/* context.c -- IOCTLs for contexts and DMA queues -*- c -*-
+ * Created: Tue Feb 2 08:37:54 1999 by faith@precisioninsight.com
+ * Revised: Fri Aug 20 11:32:09 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/context.c,v 1.5 1999/08/30 13:05:00 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/context.c,v 1.1 1999/09/25 14:37:58 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+static int drm_init_queue(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx)
+{
+ DRM_DEBUG("\n");
+
+ if (atomic_read(&q->use_count) != 1
+ || atomic_read(&q->finalization)
+ || atomic_read(&q->block_count)) {
+ DRM_ERROR("New queue is already in use: u%d f%d b%d\n",
+ atomic_read(&q->use_count),
+ atomic_read(&q->finalization),
+ atomic_read(&q->block_count));
+ }
+
+ atomic_set(&q->finalization, 0);
+ atomic_set(&q->block_count, 0);
+ atomic_set(&q->block_read, 0);
+ atomic_set(&q->block_write, 0);
+ atomic_set(&q->total_queued, 0);
+ atomic_set(&q->total_flushed, 0);
+ atomic_set(&q->total_locks, 0);
+
+ q->write_queue = 0;
+ q->read_queue = 0;
+ q->flush_queue = 0;
+
+ q->flags = ctx->flags;
+
+ drm_waitlist_create(&q->waitlist, dev->dma->buf_count);
+
+ return 0;
+}
+
+
+/* drm_alloc_queue:
+PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and will not
+ disappear (so all deallocation must be done after IOCTLs are off)
+ 2) dev->queue_count < dev->queue_slots
+ 3) dev->queuelist[i].use_count == 0 and
+ dev->queuelist[i].finalization == 0 if i not in use
+POST: 1) dev->queuelist[i].use_count == 1
+ 2) dev->queue_count < dev->queue_slots */
+
+static int drm_alloc_queue(drm_device_t *dev)
+{
+ int i;
+ drm_queue_t *queue;
+ int oldslots;
+ int newslots;
+ /* Check for a free queue */
+ for (i = 0; i < dev->queue_count; i++) {
+ atomic_inc(&dev->queuelist[i]->use_count);
+ if (atomic_read(&dev->queuelist[i]->use_count) == 1
+ && !atomic_read(&dev->queuelist[i]->finalization)) {
+ DRM_DEBUG("%d (free)\n", i);
+ return i;
+ }
+ atomic_dec(&dev->queuelist[i]->use_count);
+ }
+ /* Allocate a new queue */
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc);
+
+ queue = drm_alloc(sizeof(*queue), DRM_MEM_QUEUES);
+ memset(queue, 0, sizeof(*queue));
+ atomic_set(&queue->use_count, 1);
+
+ ++dev->queue_count;
+ if (dev->queue_count >= dev->queue_slots) {
+ oldslots = dev->queue_slots * sizeof(*dev->queuelist);
+ if (!dev->queue_slots) dev->queue_slots = 1;
+ dev->queue_slots *= 2;
+ newslots = dev->queue_slots * sizeof(*dev->queuelist);
+
+ dev->queuelist = drm_realloc(dev->queuelist,
+ oldslots,
+ newslots,
+ DRM_MEM_QUEUES);
+ if (!dev->queuelist) {
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+ DRM_DEBUG("out of memory\n");
+ return -ENOMEM;
+ }
+ }
+ dev->queuelist[dev->queue_count-1] = queue;
+
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+ DRM_DEBUG("%d (new)\n", dev->queue_count - 1);
+ return dev->queue_count - 1;
+}
+
+int drm_resctx(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_ctx_res_t res;
+ drm_ctx_t ctx;
+ int i;
+ int error;
+
+ DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
+ res = *(drm_ctx_res_t *) data;
+ if (res.count >= DRM_RESERVED_CONTEXTS) {
+ memset(&ctx, 0, sizeof(ctx));
+ for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
+ ctx.handle = i;
+ error = copyout(&i, &res.contexts[i],
+ sizeof(i));
+ if (error) return error;
+ }
+ }
+ res.count = DRM_RESERVED_CONTEXTS;
+ *(drm_ctx_res_t *) data = res;
+ return 0;
+}
+
+
+int drm_addctx(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_ctx_t ctx;
+
+ ctx = *(drm_ctx_t *) data;
+ if ((ctx.handle = drm_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
+ /* Init kernel's context and get a new one. */
+ drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx);
+ ctx.handle = drm_alloc_queue(dev);
+ }
+ drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx);
+ DRM_DEBUG("%d\n", ctx.handle);
+ *(drm_ctx_t *) data = ctx;
+ return 0;
+}
+
+int drm_modctx(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_ctx_t ctx;
+ drm_queue_t *q;
+
+ ctx = *(drm_ctx_t *) data;
+
+ DRM_DEBUG("%d\n", ctx.handle);
+
+ if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL;
+ q = dev->queuelist[ctx.handle];
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) == 1) {
+ /* No longer in use */
+ atomic_dec(&q->use_count);
+ return -EINVAL;
+ }
+
+ if (DRM_BUFCOUNT(&q->waitlist)) {
+ atomic_dec(&q->use_count);
+ return -EBUSY;
+ }
+
+ q->flags = ctx.flags;
+
+ atomic_dec(&q->use_count);
+ return 0;
+}
+
+int drm_getctx(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_ctx_t ctx;
+ drm_queue_t *q;
+
+ ctx = *(drm_ctx_t *) data;
+
+ DRM_DEBUG("%d\n", ctx.handle);
+
+ if (ctx.handle >= dev->queue_count) return -EINVAL;
+ q = dev->queuelist[ctx.handle];
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) == 1) {
+ /* No longer in use */
+ atomic_dec(&q->use_count);
+ return -EINVAL;
+ }
+
+ ctx.flags = q->flags;
+ atomic_dec(&q->use_count);
+
+ *(drm_ctx_t *) data = ctx;
+
+ return 0;
+}
+
+int drm_switchctx(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_ctx_t ctx;
+
+ ctx = *(drm_ctx_t *) data;
+ DRM_DEBUG("%d\n", ctx.handle);
+ return drm_context_switch(dev, dev->last_context, ctx.handle);
+}
+
+int drm_newctx(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_ctx_t ctx;
+
+ ctx = *(drm_ctx_t *) data;
+ DRM_DEBUG("%d\n", ctx.handle);
+ drm_context_switch_complete(dev, ctx.handle);
+
+ return 0;
+}
+
+int drm_rmctx(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_ctx_t ctx;
+ drm_queue_t *q;
+ drm_buf_t *buf;
+
+ ctx = *(drm_ctx_t *) data;
+ DRM_DEBUG("%d\n", ctx.handle);
+
+ if (ctx.handle >= dev->queue_count) return -EINVAL;
+ q = dev->queuelist[ctx.handle];
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) == 1) {
+ /* No longer in use */
+ atomic_dec(&q->use_count);
+ return -EINVAL;
+ }
+
+ atomic_inc(&q->finalization); /* Mark queue in finalization state */
+ atomic_sub(2, &q->use_count); /* Mark queue as unused (pending
+ finalization) */
+
+ /* Wait while interrupt servicing is in progress */
+ while (test_and_set_bit(0, &dev->interrupt_flag)) {
+ int never;
+ int error = tsleep(&never, PZERO|PCATCH, "drmrc", 1);
+ if (error) {
+ clear_bit(0, &dev->interrupt_flag);
+ return error;
+ }
+ }
+ /* Remove queued buffers */
+ while ((buf = drm_waitlist_get(&q->waitlist))) {
+ drm_free_buffer(dev, buf);
+ }
+ clear_bit(0, &dev->interrupt_flag);
+
+ /* Wakeup blocked processes */
+ wakeup(&q->read_queue);
+ wakeup(&q->write_queue);
+ wakeup(&q->flush_queue);
+
+ /* Finalization over. Queue is made
+ available when both use_count and
+ finalization become 0, which won't
+ happen until all the waiting processes
+ stop waiting. */
+ atomic_dec(&q->finalization);
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/dma.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/dma.c
new file mode 100644
index 000000000..149f45934
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/dma.c
@@ -0,0 +1,534 @@
+/* dma.c -- DMA IOCTL and function support -*- c -*-
+ * Created: Fri Mar 19 14:30:16 1999 by faith@precisioninsight.com
+ * Revised: Thu Sep 16 12:55:39 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dma.c,v 1.7 1999/09/16 16:56:18 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dma.c,v 1.1 1999/09/25 14:37:58 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+void drm_dma_setup(drm_device_t *dev)
+{
+ int i;
+
+ dev->dma = drm_alloc(sizeof(*dev->dma), DRM_MEM_DRIVER);
+ memset(dev->dma, 0, sizeof(*dev->dma));
+ for (i = 0; i <= DRM_MAX_ORDER; i++)
+ memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
+}
+
+void drm_dma_takedown(drm_device_t *dev)
+{
+ drm_device_dma_t *dma = dev->dma;
+ int i, j;
+
+ if (!dma) return;
+
+ /* Clear dma buffers */
+ for (i = 0; i <= DRM_MAX_ORDER; i++) {
+ if (dma->bufs[i].seg_count) {
+ DRM_DEBUG("order %d: buf_count = %d,"
+ " seg_count = %d\n",
+ i,
+ dma->bufs[i].buf_count,
+ dma->bufs[i].seg_count);
+ for (j = 0; j < dma->bufs[i].seg_count; j++) {
+ drm_free_pages(dma->bufs[i].seglist[j],
+ dma->bufs[i].page_order,
+ DRM_MEM_DMA);
+ }
+ drm_free(dma->bufs[i].buflist,
+ dma->buf_count
+ * sizeof(*dma->bufs[0].buflist),
+ DRM_MEM_BUFS);
+ drm_free(dma->bufs[i].seglist,
+ dma->buf_count
+ * sizeof(*dma->bufs[0].seglist),
+ DRM_MEM_SEGS);
+ drm_freelist_destroy(&dma->bufs[i].freelist);
+ }
+ }
+
+ if (dma->buflist) {
+ drm_free(dma->buflist,
+ dma->buf_count * sizeof(*dma->buflist),
+ DRM_MEM_BUFS);
+ }
+
+ if (dma->pagelist) {
+ drm_free(dma->pagelist,
+ dma->page_count * sizeof(*dma->pagelist),
+ DRM_MEM_PAGES);
+ }
+ drm_free(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
+ dev->dma = NULL;
+}
+
+#if DRM_DMA_HISTOGRAM
+/* This is slow, but is useful for debugging. */
+int drm_histogram_slot(struct timespec *ts)
+{
+ long count = ts->tv_sec * 1000 + ts->tv_nsec / 1000000;
+ int value = DRM_DMA_HISTOGRAM_INITIAL;
+ int slot;
+
+ for (slot = 0;
+ slot < DRM_DMA_HISTOGRAM_SLOTS;
+ ++slot, value = DRM_DMA_HISTOGRAM_NEXT(value)) {
+ if (count < value) return slot;
+ }
+ return DRM_DMA_HISTOGRAM_SLOTS - 1;
+}
+
+void drm_histogram_compute(drm_device_t *dev, drm_buf_t *buf)
+{
+ struct timespec queued_to_dispatched;
+ struct timespec dispatched_to_completed;
+ struct timespec completed_to_freed;
+ int q2d, d2c, c2f, q2c, q2f;
+
+ if (timespecisset(&buf->time_queued)) {
+ queued_to_dispatched = buf->time_dispatched;
+ timespecsub(&queued_to_dispatched, &buf->time_queued);
+ dispatched_to_completed = buf->time_completed;
+ timespecsub(&dispatched_to_completed, &buf->time_dispatched);
+ completed_to_freed = buf->time_freed;
+ timespecsub(&completed_to_freed, &buf->time_completed);
+
+ q2d = drm_histogram_slot(&queued_to_dispatched);
+ d2c = drm_histogram_slot(&dispatched_to_completed);
+ c2f = drm_histogram_slot(&completed_to_freed);
+
+ timespecadd(&queued_to_dispatched, &dispatched_to_completed);
+ q2c = drm_histogram_slot(&queued_to_dispatched);
+ timespecadd(&queued_to_dispatched, &completed_to_freed);
+ q2f = drm_histogram_slot(&queued_to_dispatched);
+
+ atomic_inc(&dev->histo.total);
+ atomic_inc(&dev->histo.queued_to_dispatched[q2d]);
+ atomic_inc(&dev->histo.dispatched_to_completed[d2c]);
+ atomic_inc(&dev->histo.completed_to_freed[c2f]);
+
+ atomic_inc(&dev->histo.queued_to_completed[q2c]);
+ atomic_inc(&dev->histo.queued_to_freed[q2f]);
+
+ }
+ timespecclear(&buf->time_queued);
+ timespecclear(&buf->time_dispatched);
+ timespecclear(&buf->time_completed);
+ timespecclear(&buf->time_freed);
+}
+#endif
+
+void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
+{
+ drm_device_dma_t *dma = dev->dma;
+
+ if (!buf) return;
+
+ buf->waiting = 0;
+ buf->pending = 0;
+ buf->pid = 0;
+ buf->used = 0;
+#if DRM_DMA_HISTOGRAMxx
+ buf->time_completed = get_cycles();
+#endif
+ if (buf->dma_wait) {
+ buf->dma_wait = 0;
+ wakeup(&buf->dma_wait);
+ } else {
+ /* If processes are waiting, the last one
+ to wake will put the buffer on the free
+ list. If no processes are waiting, we
+ put the buffer on the freelist here. */
+ drm_freelist_put(dev, &dma->bufs[buf->order].freelist, buf);
+ }
+}
+
+void drm_reclaim_buffers(drm_device_t *dev, pid_t pid)
+{
+ drm_device_dma_t *dma = dev->dma;
+ int i;
+
+ if (!dma) return;
+ for (i = 0; i < dma->buf_count; i++) {
+ if (dma->buflist[i]->pid == pid) {
+ switch (dma->buflist[i]->list) {
+ case DRM_LIST_NONE:
+ drm_free_buffer(dev, dma->buflist[i]);
+ break;
+ case DRM_LIST_WAIT:
+ dma->buflist[i]->list = DRM_LIST_RECLAIM;
+ break;
+ default:
+ /* Buffer already on hardware. */
+ break;
+ }
+ }
+ }
+}
+
+int drm_context_switch(drm_device_t *dev, int old, int new)
+{
+ char buf[64];
+ drm_queue_t *q;
+
+ atomic_inc(&dev->total_ctx);
+
+ if (test_and_set_bit(0, &dev->context_flag)) {
+ DRM_ERROR("Reentering -- FIXME\n");
+ return EBUSY;
+ }
+
+#if DRM_DMA_HISTOGRAM
+ getnanotime(&dev->ctx_start);
+#endif
+
+ DRM_DEBUG("Context switch from %d to %d\n", old, new);
+
+ if (new >= dev->queue_count) {
+ clear_bit(0, &dev->context_flag);
+ return EINVAL;
+ }
+
+ if (new == dev->last_context) {
+ clear_bit(0, &dev->context_flag);
+ return 0;
+ }
+
+ q = dev->queuelist[new];
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) == 1) {
+ atomic_dec(&q->use_count);
+ clear_bit(0, &dev->context_flag);
+ return EINVAL;
+ }
+
+ if (drm_flags & DRM_FLAG_NOCTX) {
+ drm_context_switch_complete(dev, new);
+ } else {
+ sprintf(buf, "C %d %d\n", old, new);
+ drm_write_string(dev, buf);
+ }
+
+ atomic_dec(&q->use_count);
+
+ return 0;
+}
+
+int drm_context_switch_complete(drm_device_t *dev, int new)
+{
+ drm_device_dma_t *dma = dev->dma;
+
+ dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
+ dev->last_switch = ticks;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("Lock isn't held after context switch\n");
+ }
+
+ if (!dma || !(dma->next_buffer && dma->next_buffer->while_locked)) {
+ if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ DRM_ERROR("Cannot free lock\n");
+ }
+ }
+
+#if DRM_DMA_HISTOGRAM
+ {
+ struct timespec ts;
+ getnanotime(&ts);
+ timespecsub(&ts, &dev->ctx_start);
+ atomic_inc(&dev->histo.ctx[drm_histogram_slot(&ts)]);
+ }
+#endif
+ clear_bit(0, &dev->context_flag);
+ wakeup(&dev->context_wait);
+
+ return 0;
+}
+
+void drm_clear_next_buffer(drm_device_t *dev)
+{
+ drm_device_dma_t *dma = dev->dma;
+
+ dma->next_buffer = NULL;
+ if (dma->next_queue && !DRM_BUFCOUNT(&dma->next_queue->waitlist)) {
+ wakeup(&dma->next_queue->flush_queue);
+ }
+ dma->next_queue = NULL;
+}
+
+
+int drm_select_queue(drm_device_t *dev, void (*wrapper)(void *))
+{
+ int i;
+ int candidate = -1;
+ int j = ticks;
+
+ if (!dev) {
+ DRM_ERROR("No device\n");
+ return -1;
+ }
+ if (!dev->queuelist || !dev->queuelist[DRM_KERNEL_CONTEXT]) {
+ /* This only happens between the time the
+ interrupt is initialized and the time
+ the queues are initialized. */
+ return -1;
+ }
+
+ /* Doing "while locked" DMA? */
+ if (DRM_WAITCOUNT(dev, DRM_KERNEL_CONTEXT)) {
+ return DRM_KERNEL_CONTEXT;
+ }
+
+ /* If there are buffers on the last_context
+ queue, and we have not been executing
+ this context very long, continue to
+ execute this context. */
+ if (dev->last_switch <= j
+ && dev->last_switch + DRM_TIME_SLICE > j
+ && DRM_WAITCOUNT(dev, dev->last_context)) {
+ return dev->last_context;
+ }
+
+ /* Otherwise, find a candidate */
+ for (i = dev->last_checked + 1; i < dev->queue_count; i++) {
+ if (DRM_WAITCOUNT(dev, i)) {
+ candidate = dev->last_checked = i;
+ break;
+ }
+ }
+
+ if (candidate < 0) {
+ for (i = 0; i < dev->queue_count; i++) {
+ if (DRM_WAITCOUNT(dev, i)) {
+ candidate = dev->last_checked = i;
+ break;
+ }
+ }
+ }
+
+ if (wrapper
+ && candidate >= 0
+ && candidate != dev->last_context
+ && dev->last_switch <= j
+ && dev->last_switch + DRM_TIME_SLICE > j) {
+ int s = splclock();
+ if (dev->timer.c_time != dev->last_switch + DRM_TIME_SLICE) {
+ callout_reset(&dev->timer,
+ dev->last_switch + DRM_TIME_SLICE - j,
+ wrapper,
+ dev);
+ }
+ splx(s);
+ return -1;
+ }
+
+ return candidate;
+}
+
+
+int drm_dma_enqueue(drm_device_t *dev, drm_dma_t *d)
+{
+ int i;
+ drm_queue_t *q;
+ drm_buf_t *buf;
+ int idx;
+ int while_locked = 0;
+ drm_device_dma_t *dma = dev->dma;
+ int error;
+
+ DRM_DEBUG("%d\n", d->send_count);
+
+ if (d->flags & _DRM_DMA_WHILE_LOCKED) {
+ int context = dev->lock.hw_lock->lock;
+
+ if (!_DRM_LOCK_IS_HELD(context)) {
+ DRM_ERROR("No lock held during \"while locked\""
+ " request\n");
+ return EINVAL;
+ }
+ if (d->context != _DRM_LOCKING_CONTEXT(context)
+ && _DRM_LOCKING_CONTEXT(context) != DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("Lock held by %d while %d makes"
+ " \"while locked\" request\n",
+ _DRM_LOCKING_CONTEXT(context),
+ d->context);
+ return EINVAL;
+ }
+ q = dev->queuelist[DRM_KERNEL_CONTEXT];
+ while_locked = 1;
+ } else {
+ q = dev->queuelist[d->context];
+ }
+
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->block_write)) {
+ atomic_inc(&q->block_count);
+ for (;;) {
+ if (!atomic_read(&q->block_write)) break;
+ error = tsleep(&q->block_write, PZERO|PCATCH,
+ "dmawr", 0);
+ if (error) {
+ atomic_dec(&q->use_count);
+ return error;
+ }
+ }
+ atomic_dec(&q->block_count);
+ }
+
+ for (i = 0; i < d->send_count; i++) {
+ idx = d->send_indices[i];
+ if (idx < 0 || idx >= dma->buf_count) {
+ atomic_dec(&q->use_count);
+ DRM_ERROR("Index %d (of %d max)\n",
+ d->send_indices[i], dma->buf_count - 1);
+ return EINVAL;
+ }
+ buf = dma->buflist[ idx ];
+ if (buf->pid != curproc->p_pid) {
+ atomic_dec(&q->use_count);
+ DRM_ERROR("Process %d using buffer owned by %d\n",
+ curproc->p_pid, buf->pid);
+ return EINVAL;
+ }
+ if (buf->list != DRM_LIST_NONE) {
+ atomic_dec(&q->use_count);
+ DRM_ERROR("Process %d using buffer %d on list %d\n",
+ curproc->p_pid, buf->idx, buf->list);
+ }
+ buf->used = d->send_sizes[i];
+ buf->while_locked = while_locked;
+ buf->context = d->context;
+ if (!buf->used) {
+ DRM_ERROR("Queueing 0 length buffer\n");
+ }
+ if (buf->pending) {
+ atomic_dec(&q->use_count);
+ DRM_ERROR("Queueing pending buffer:"
+ " buffer %d, offset %d\n",
+ d->send_indices[i], i);
+ return EINVAL;
+ }
+ if (buf->waiting) {
+ atomic_dec(&q->use_count);
+ DRM_ERROR("Queueing waiting buffer:"
+ " buffer %d, offset %d\n",
+ d->send_indices[i], i);
+ return EINVAL;
+ }
+ buf->waiting = 1;
+ if (atomic_read(&q->use_count) == 1
+ || atomic_read(&q->finalization)) {
+ drm_free_buffer(dev, buf);
+ } else {
+ drm_waitlist_put(&q->waitlist, buf);
+ atomic_inc(&q->total_queued);
+ }
+ }
+ atomic_dec(&q->use_count);
+
+ return 0;
+}
+
+static int drm_dma_get_buffers_of_order(drm_device_t *dev, drm_dma_t *d,
+ int order)
+{
+ int i;
+ int error;
+ drm_buf_t *buf;
+ drm_device_dma_t *dma = dev->dma;
+
+ for (i = d->granted_count; i < d->request_count; i++) {
+ buf = drm_freelist_get(&dma->bufs[order].freelist,
+ d->flags & _DRM_DMA_WAIT);
+ if (!buf) break;
+ if (buf->pending || buf->waiting) {
+ DRM_ERROR("Free buffer %d in use by %d (w%d, p%d)\n",
+ buf->idx,
+ buf->pid,
+ buf->waiting,
+ buf->pending);
+ }
+ buf->pid = curproc->p_pid;
+ error = copyout(&buf->idx,
+ &d->request_indices[i],
+ sizeof(buf->idx));
+ if (error)
+ return error;
+ error = copyout(&buf->total,
+ &d->request_sizes[i],
+ sizeof(buf->total));
+ if (error)
+ return error;
+ ++d->granted_count;
+ }
+ return 0;
+}
+
+
+int drm_dma_get_buffers(drm_device_t *dev, drm_dma_t *dma)
+{
+ int order;
+ int retcode = 0;
+ int tmp_order;
+
+ order = drm_order(dma->request_size);
+
+ dma->granted_count = 0;
+ retcode = drm_dma_get_buffers_of_order(dev, dma, order);
+
+ if (dma->granted_count < dma->request_count
+ && (dma->flags & _DRM_DMA_SMALLER_OK)) {
+ for (tmp_order = order - 1;
+ !retcode
+ && dma->granted_count < dma->request_count
+ && tmp_order >= DRM_MIN_ORDER;
+ --tmp_order) {
+
+ retcode = drm_dma_get_buffers_of_order(dev, dma,
+ tmp_order);
+ }
+ }
+
+ if (dma->granted_count < dma->request_count
+ && (dma->flags & _DRM_DMA_LARGER_OK)) {
+ for (tmp_order = order + 1;
+ !retcode
+ && dma->granted_count < dma->request_count
+ && tmp_order <= DRM_MAX_ORDER;
+ ++tmp_order) {
+
+ retcode = drm_dma_get_buffers_of_order(dev, dma,
+ tmp_order);
+ }
+ }
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/drawable.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/drawable.c
new file mode 100644
index 000000000..d8005af6a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/drawable.c
@@ -0,0 +1,50 @@
+/* drawable.c -- IOCTLs for drawables -*- c -*-
+ * Created: Tue Feb 2 08:37:54 1999 by faith@precisioninsight.com
+ * Revised: Fri Aug 20 09:27:03 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drawable.c,v 1.3 1999/08/30 13:05:00 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drawable.c,v 1.1 1999/09/25 14:37:58 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+int drm_adddraw(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_draw_t draw;
+
+ draw.handle = 0; /* NOOP */
+ DRM_DEBUG("%d\n", draw.handle);
+ *(drm_draw_t *) data = draw;
+ return 0;
+}
+
+int drm_rmdraw(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ return 0; /* NOOP */
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/drmstat.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/drmstat.c
new file mode 100644
index 000000000..0ce76b01a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/drmstat.c
@@ -0,0 +1,418 @@
+/* drmstat.c -- DRM device status and testing program
+ * Created: Tue Jan 5 08:19:24 1999 by faith@precisioninsight.com
+ * Revised: Sun Aug 1 11:02:00 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmstat.c,v 1.28 1999/08/04 18:12:11 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmstat.c,v 1.1 1999/09/25 14:37:59 dawes Exp $
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+#include <strings.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include "xf86drm.h"
+
+int sigio_fd;
+
+static double usec(struct timeval *end, struct timeval *start)
+{
+ double e = end->tv_sec * 1000000 + end->tv_usec;
+ double s = start->tv_sec * 1000000 + start->tv_usec;
+
+ return e - s;
+}
+
+static void getversion(int fd)
+{
+ drmVersionPtr version;
+
+ version = drmGetVersion(fd);
+ if (version) {
+ printf( "Name: %s\n", version->name ? version->name : "?" );
+ printf( " Version: %d.%d.%d\n",
+ version->version_major,
+ version->version_minor,
+ version->version_patchlevel );
+ printf( " Date: %s\n", version->date ? version->date : "?" );
+ printf( " Desc: %s\n", version->desc ? version->desc : "?" );
+ drmFreeVersion(version);
+ } else {
+ printf( "No driver available\n" );
+ }
+}
+
+void handler(int fd, void *oldctx, void *newctx)
+{
+ printf("Got fd %d\n", fd);
+}
+
+void process_sigio(char *device)
+{
+ int fd;
+
+printf("%s\n", device);
+ if ((fd = open(device, 0)) < 0) {
+printf("%d\n", errno);
+ drmError(-errno, __FUNCTION__);
+ exit(1);
+ }
+
+ sigio_fd = fd;
+ drmInstallSIGIOHandler(fd, handler);
+ for (;;) sleep(60);
+}
+
+int main(int argc, char **argv)
+{
+ int c;
+ int r = 0;
+ int fd = -1;
+ drmHandle handle;
+ void *address;
+ char *pt;
+ unsigned long count;
+ unsigned long offset;
+ unsigned long size;
+ drmContext context;
+ int loops;
+ char buf[1024];
+ int i;
+ drmBufInfoPtr info;
+ drmBufMapPtr bufs;
+ drmLockPtr lock;
+ int secs;
+
+ while ((c = getopt(argc, argv,
+ "lc:vo:O:f:s:w:W:b:r:R:P:L:C:XS:B:F:")) != EOF)
+ switch (c) {
+ case 'F':
+ count = strtoul(optarg, NULL, 0);
+ if (!fork()) {
+ dup(fd);
+ sleep(count);
+ }
+ close(fd);
+ break;
+ case 'v': getversion(fd); break;
+ case 'X':
+ if ((r = drmCreateContext(fd, &context))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ printf( "Got %d\n", context);
+ break;
+ case 'S':
+ process_sigio(optarg);
+ break;
+ case 'C':
+ if ((r = drmSwitchToContext(fd, strtoul(optarg, NULL, 0)))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ break;
+ case 'c':
+ if ((r = drmSetBusid(fd,optarg))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ break;
+ case 'o':
+ if ((fd = drmOpen(optarg, NULL)) < 0) {
+ drmError(fd, argv[0]);
+ return 1;
+ }
+ break;
+ case 'O':
+ if ((fd = drmOpen(NULL, optarg)) < 0) {
+ drmError(fd, argv[0]);
+ return 1;
+ }
+ break;
+ case 'B': /* Test buffer allocation */
+ count = strtoul(optarg, &pt, 0);
+ size = strtoul(pt+1, &pt, 0);
+ secs = strtoul(pt+1, NULL, 0);
+ {
+ drmDMAReq dma;
+ int *indices, *sizes;
+
+ indices = alloca(sizeof(*indices) * count);
+ sizes = alloca(sizeof(*sizes) * count);
+ dma.context = context;
+ dma.send_count = 0;
+ dma.request_count = count;
+ dma.request_size = size;
+ dma.request_list = indices;
+ dma.request_sizes = sizes;
+ dma.flags = DRM_DMA_WAIT;
+ if ((r = drmDMA(fd, &dma))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ for (i = 0; i < dma.granted_count; i++) {
+ printf("%5d: index = %d, size = %d\n",
+ i, dma.request_list[i], dma.request_sizes[i]);
+ }
+ sleep(secs);
+ drmFreeBufs(fd, dma.granted_count, indices);
+ }
+ break;
+ case 'b':
+ count = strtoul(optarg, &pt, 0);
+ size = strtoul(pt+1, NULL, 0);
+ if ((r = drmAddBufs(fd, count, size, 0, 0)) < 0) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ if (!(info = drmGetBufInfo(fd))) {
+ drmError(0, argv[0]);
+ return 1;
+ }
+ for (i = 0; i < info->count; i++) {
+ printf("%5d buffers of size %6d (low = %d, high = %d)\n",
+ info->list[i].count,
+ info->list[i].size,
+ info->list[i].low_mark,
+ info->list[i].high_mark);
+ }
+ if ((r = drmMarkBufs(fd, 0.50, 0.80))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ if (!(info = drmGetBufInfo(fd))) {
+ drmError(0, argv[0]);
+ return 1;
+ }
+ for (i = 0; i < info->count; i++) {
+ printf("%5d buffers of size %6d (low = %d, high = %d)\n",
+ info->list[i].count,
+ info->list[i].size,
+ info->list[i].low_mark,
+ info->list[i].high_mark);
+ }
+ printf("===== /proc/drm/1/meminfo =====\n");
+ sprintf(buf, "cat /proc/drm/1/meminfo");
+ system(buf);
+#if 1
+ if (!(bufs = drmMapBufs(fd))) {
+ drmError(0, argv[0]);
+ return 1;
+ }
+ printf("===============================\n");
+ printf( "%d bufs\n", bufs->count);
+ for (i = 0; i < bufs->count; i++) {
+ printf( " %4d: %8d bytes at %p\n",
+ i,
+ bufs->list[i].total,
+ bufs->list[i].address);
+ }
+ printf("===== /proc/drm/1/vmainfo =====\n");
+ sprintf(buf, "cat /proc/drm/1/vmainfo");
+ system(buf);
+#endif
+ break;
+ case 'f':
+ offset = strtoul(optarg, &pt, 0);
+ size = strtoul(pt+1, NULL, 0);
+ handle = 0;
+ if ((r = drmAddMap(fd, offset, size,
+ DRM_FRAME_BUFFER, 0, &handle))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ printf("0x%08lx:0x%04lx added\n", offset, size);
+ printf("===== /proc/drm/1/meminfo =====\n");
+ sprintf(buf, "cat /proc/drm/1/meminfo");
+ system(buf);
+ break;
+ case 'r':
+ case 'R':
+ offset = strtoul(optarg, &pt, 0);
+ size = strtoul(pt+1, NULL, 0);
+ handle = 0;
+ if ((r = drmAddMap(fd, offset, size,
+ DRM_REGISTERS,
+ c == 'R' ? DRM_READ_ONLY : 0,
+ &handle))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ printf("0x%08lx:0x%04lx added\n", offset, size);
+ printf("===== /proc/drm/1/meminfo =====\n");
+ sprintf(buf, "cat /proc/drm/1/meminfo");
+ system(buf);
+ break;
+ case 's':
+ size = strtoul(optarg, &pt, 0);
+ handle = 0;
+ if ((r = drmAddMap(fd, 0, size,
+ DRM_SHM, DRM_CONTAINS_LOCK,
+ &handle))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ printf("0x%04lx byte shm added at 0x%08lx\n", size, handle);
+ sprintf(buf, "sysctl hw.graphics.0.vm");
+ system(buf);
+ break;
+ case 'P':
+ offset = strtoul(optarg, &pt, 0);
+ size = strtoul(pt+1, NULL, 0);
+ address = NULL;
+ if ((r = drmMap(fd, offset, size, &address))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ printf("0x%08lx:0x%04lx mapped at %p for pid %d\n",
+ offset, size, address, getpid());
+ printf("===== hw.graphics.0.vma =====\n");
+ sprintf(buf, "sysctl hw.graphics.0.vma");
+ system(buf);
+ mprotect((void *)offset, size, PROT_READ);
+ printf("===== hw.graphics.0.vma =====\n");
+ sprintf(buf, "sysctl hw.graphics.0.vma");
+ system(buf);
+ break;
+ case 'w':
+ case 'W':
+ offset = strtoul(optarg, &pt, 0);
+ size = strtoul(pt+1, NULL, 0);
+ address = NULL;
+ if ((r = drmMap(fd, offset, size, &address))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ printf("0x%08lx:0x%04lx mapped at %p for pid %d\n",
+ offset, size, address, getpid());
+ printf("===== /proc/%d/maps =====\n", getpid());
+ sprintf(buf, "cat /proc/%d/maps", getpid());
+ system(buf);
+ printf("===== /proc/drm/1/meminfo =====\n");
+ sprintf(buf, "cat /proc/drm/1/meminfo");
+ system(buf);
+ printf("===== /proc/drm/1/vmainfo =====\n");
+ sprintf(buf, "cat /proc/drm/1/vmainfo");
+ system(buf);
+ printf("===== READING =====\n");
+ for (i = 0; i < 0x10; i++)
+ printf("%02x ", (unsigned int)((unsigned char *)address)[i]);
+ printf("\n");
+ if (c == 'w') {
+ printf("===== WRITING =====\n");
+ for (i = 0; i < size; i+=2) {
+ ((char *)address)[i] = i & 0xff;
+ ((char *)address)[i+1] = i & 0xff;
+ }
+ }
+ printf("===== READING =====\n");
+ for (i = 0; i < 0x10; i++)
+ printf("%02x ", (unsigned int)((unsigned char *)address)[i]);
+ printf("\n");
+ printf("===== /proc/drm/1/vmainfo =====\n");
+ sprintf(buf, "cat /proc/drm/1/vmainfo");
+ system(buf);
+ break;
+ case 'L':
+ context = strtoul(optarg, &pt, 0);
+ offset = strtoul(pt+1, &pt, 0);
+ size = strtoul(pt+1, &pt, 0);
+ loops = strtoul(pt+1, NULL, 0);
+ address = NULL;
+ if ((r = drmMap(fd, offset, size, &address))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ lock = address;
+#if 1
+ {
+ int counter = 0;
+ struct timeval loop_start, loop_end;
+ struct timeval lock_start, lock_end;
+ double wt;
+#define HISTOSIZE 9
+ int histo[HISTOSIZE];
+ int output = 0;
+ int fast = 0;
+
+ if (loops < 0) {
+ loops = -loops;
+ ++output;
+ }
+
+ for (i = 0; i < HISTOSIZE; i++) histo[i] = 0;
+
+ gettimeofday(&loop_start, NULL);
+ for (i = 0; i < loops; i++) {
+ gettimeofday(&lock_start, NULL);
+ DRM_LIGHT_LOCK_COUNT(fd,lock,context,fast);
+ gettimeofday(&lock_end, NULL);
+ DRM_UNLOCK(fd,lock,context);
+ ++counter;
+ wt = usec(&lock_end, &lock_start);
+ if (wt <= 2.5) ++histo[8];
+ if (wt < 5.0) ++histo[0];
+ else if (wt < 50.0) ++histo[1];
+ else if (wt < 500.0) ++histo[2];
+ else if (wt < 5000.0) ++histo[3];
+ else if (wt < 50000.0) ++histo[4];
+ else if (wt < 500000.0) ++histo[5];
+ else if (wt < 5000000.0) ++histo[6];
+ else ++histo[7];
+ if (output) printf( "%.2f uSec, %d fast\n", wt, fast);
+ }
+ gettimeofday(&loop_end, NULL);
+ printf( "Average wait time = %.2f usec, %d fast\n",
+ usec(&loop_end, &loop_start) / counter, fast);
+ printf( "%9d <= 2.5 uS\n", histo[8]);
+ printf( "%9d < 5 uS\n", histo[0]);
+ printf( "%9d < 50 uS\n", histo[1]);
+ printf( "%9d < 500 uS\n", histo[2]);
+ printf( "%9d < 5000 uS\n", histo[3]);
+ printf( "%9d < 50000 uS\n", histo[4]);
+ printf( "%9d < 500000 uS\n", histo[5]);
+ printf( "%9d < 5000000 uS\n", histo[6]);
+ printf( "%9d >= 5000000 uS\n", histo[7]);
+ }
+#else
+ printf( "before lock: 0x%08x\n", lock->lock);
+ printf( "lock: 0x%08x\n", lock->lock);
+ sleep(5);
+ printf( "unlock: 0x%08x\n", lock->lock);
+#endif
+ break;
+ default:
+ fprintf( stderr, "Usage: drmstat [options]\n" );
+ return 1;
+ }
+
+ return r;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/fops.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/fops.c
new file mode 100644
index 000000000..837fc7db0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/fops.c
@@ -0,0 +1,260 @@
+/* fops.c -- File operations for DRM -*- c -*-
+ * Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com
+ * Revised: Tue Oct 12 08:48:59 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/fops.c,v 1.3 1999/08/20 15:36:45 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/fops.c,v 1.1 1999/09/25 14:37:59 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+#include <sys/signalvar.h>
+#include <sys/poll.h>
+
+drm_file_t *drm_find_file_by_proc(drm_device_t *dev, struct proc *p)
+{
+ uid_t uid = p->p_cred->p_svuid;
+ pid_t pid = p->p_pid;
+ drm_file_t *priv;
+
+ TAILQ_FOREACH(priv, &dev->files, link)
+ if (priv->pid == pid && priv->uid == uid)
+ return priv;
+ return NULL;
+}
+
+
+/* drm_open is called whenever a process opens /dev/drm. */
+
+int drm_open_helper(dev_t kdev, int flags, int fmt, struct proc *p,
+ drm_device_t *dev)
+{
+ int m = minor(kdev);
+ drm_file_t *priv;
+
+ if (flags & O_EXCL)
+ return EBUSY; /* No exclusive opens */
+
+ dev->flags = flags;
+
+ DRM_DEBUG("pid = %d, device = %p, minor = %d\n",
+ p->p_pid, dev->device, m);
+
+ priv = drm_find_file_by_proc(dev, p);
+ if (priv) {
+ priv->refs++;
+ } else {
+ priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
+ memset(priv, 0, sizeof(*priv));
+ priv->uid = p->p_cred->p_svuid;
+ priv->pid = p->p_pid;
+ priv->refs = 1;
+ priv->minor = m;
+ priv->devXX = dev;
+ priv->ioctl_count = 0;
+ priv->authenticated = !suser(p);
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, p);
+ TAILQ_INSERT_TAIL(&dev->files, priv, link);
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, p);
+ }
+
+ kdev->si_drv1 = dev;
+
+ return 0;
+}
+
+int drm_write(dev_t kdev, struct uio *uio, int ioflag)
+{
+ struct proc *p = curproc;
+ drm_device_t *dev = kdev->si_drv1;
+
+ DRM_DEBUG("pid = %d, device = %p, open_count = %d\n",
+ p->p_pid, dev->device, dev->open_count);
+ return 0;
+}
+
+/* drm_release is called whenever a process closes /dev/drm*. */
+
+int drm_close(dev_t kdev, int fflag, int devtype, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_file_t *priv;
+
+ DRM_DEBUG("pid = %d, device = %p, open_count = %d\n",
+ p->p_pid, dev->device, dev->open_count);
+
+ priv = drm_find_file_by_proc(dev, p);
+ if (!priv) {
+ DRM_DEBUG("can't find authenticator\n");
+ return EINVAL;
+ }
+
+ if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
+ && dev->lock.pid == p->p_pid) {
+ DRM_ERROR("Process %d dead, freeing lock for context %d\n",
+ p->p_pid,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+ drm_lock_free(dev,
+ &dev->lock.hw_lock->lock,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+
+ /* FIXME: may require heavy-handed reset of
+ hardware at this point, possibly
+ processed via a callback to the X
+ server. */
+ }
+ drm_reclaim_buffers(dev, priv->pid);
+
+ funsetown(dev->buf_sigio);
+
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, p);
+ priv = drm_find_file_by_proc(dev, p);
+ if (priv) {
+ priv->refs--;
+ if (!priv->refs) {
+ TAILQ_REMOVE(&dev->files, priv, link);
+ drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
+ }
+ }
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, p);
+
+ return 0;
+}
+
+/* The drm_read and drm_write_string code (especially that which manages
+ the circular buffer), is based on Alessandro Rubini's LINUX DEVICE
+ DRIVERS (Cambridge: O'Reilly, 1998), pages 111-113. */
+
+ssize_t drm_read(dev_t kdev, struct uio *uio, int ioflag)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ int left;
+ int avail;
+ int send;
+ int cur;
+ int error = 0;
+
+ DRM_DEBUG("%p, %p\n", dev->buf_rp, dev->buf_wp);
+
+ while (dev->buf_rp == dev->buf_wp) {
+ DRM_DEBUG(" sleeping\n");
+ if (dev->flags & FASYNC) {
+ return EWOULDBLOCK;
+ }
+ error = tsleep(&dev->buf_rp, PZERO|PCATCH, "drmrd", 0);
+ if (error) {
+ DRM_DEBUG(" interrupted\n");
+ return error;
+ }
+ DRM_DEBUG(" awake\n");
+ }
+
+ left = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ;
+ avail = DRM_BSZ - left;
+ send = DRM_MIN(avail, uio->uio_resid);
+
+ while (send) {
+ if (dev->buf_wp > dev->buf_rp) {
+ cur = DRM_MIN(send, dev->buf_wp - dev->buf_rp);
+ } else {
+ cur = DRM_MIN(send, dev->buf_end - dev->buf_rp);
+ }
+ error = uiomove(dev->buf_rp, cur, uio);
+ if (error)
+ break;
+ dev->buf_rp += cur;
+ if (dev->buf_rp == dev->buf_end) dev->buf_rp = dev->buf;
+ send -= cur;
+ }
+
+ wakeup(&dev->buf_wp);
+
+ return error;
+}
+
+int drm_write_string(drm_device_t *dev, const char *s)
+{
+ int left = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ;
+ int send = strlen(s);
+ int count;
+
+ DRM_DEBUG("%d left, %d to send (%p, %p)\n",
+ left, send, dev->buf_rp, dev->buf_wp);
+
+ if (left == 1 || dev->buf_wp != dev->buf_rp) {
+ DRM_ERROR("Buffer not empty (%d left, wp = %p, rp = %p)\n",
+ left,
+ dev->buf_wp,
+ dev->buf_rp);
+ }
+
+ while (send) {
+ if (dev->buf_wp >= dev->buf_rp) {
+ count = DRM_MIN(send, dev->buf_end - dev->buf_wp);
+ if (count == left) --count; /* Leave a hole */
+ } else {
+ count = DRM_MIN(send, dev->buf_rp - dev->buf_wp - 1);
+ }
+ strncpy(dev->buf_wp, s, count);
+ dev->buf_wp += count;
+ if (dev->buf_wp == dev->buf_end) dev->buf_wp = dev->buf;
+ send -= count;
+ }
+
+ if (dev->buf_selecting) {
+ dev->buf_selecting = 0;
+ selwakeup(&dev->buf_sel);
+ }
+
+ DRM_DEBUG("dev->buf_sigio=%p\n", dev->buf_sigio);
+ if (dev->buf_sigio) {
+ DRM_DEBUG("dev->buf_sigio->sio_pgid=%d\n", dev->buf_sigio->sio_pgid);
+ pgsigio(dev->buf_sigio, SIGIO, 0);
+ }
+
+ DRM_DEBUG("waking\n");
+ wakeup(&dev->buf_rp);
+ return 0;
+}
+
+int drm_poll(dev_t kdev, int events, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ int s;
+ int revents = 0;
+
+ s = spldrm();
+ if (events & (POLLIN | POLLRDNORM)) {
+ int left = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ;
+ if (left > 0)
+ revents |= events & (POLLIN | POLLRDNORM);
+ else
+ selrecord(p, &dev->buf_sel);
+ }
+ splx(s);
+
+ return revents;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/init.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/init.c
new file mode 100644
index 000000000..44e9be995
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/init.c
@@ -0,0 +1,101 @@
+/* init.c -- Setup/Cleanup for DRM -*- c -*-
+ * Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com
+ * Revised: Fri Aug 20 09:27:02 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/init.c,v 1.3 1999/08/20 15:07:01 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/init.c,v 1.1 1999/09/25 14:38:01 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+MODULE_VERSION(drm, 1);
+
+int drm_flags = 0;
+
+/* drm_parse_option parses a single option. See description for
+ drm_parse_drm for details. */
+
+static void drm_parse_option(char *s)
+{
+ char *c, *r;
+
+ DRM_DEBUG("\"%s\"\n", s);
+ if (!s || !*s) return;
+ for (c = s; *c && *c != ':'; c++); /* find : or \0 */
+ if (*c) r = c + 1; else r = NULL; /* remember remainder */
+ *c = '\0'; /* terminate */
+ if (!strcmp(s, "noctx")) {
+ drm_flags |= DRM_FLAG_NOCTX;
+ DRM_INFO("Server-mediated context switching OFF\n");
+ return;
+ }
+ if (!strcmp(s, "debug")) {
+ drm_flags |= DRM_FLAG_DEBUG;
+ DRM_INFO("Debug messages ON\n");
+ return;
+ }
+ DRM_ERROR("\"%s\" is not a valid option\n", s);
+ return;
+}
+
+/* drm_parse_options parse the insmod "drm=" options, or the command-line
+ * options passed to the kernel via LILO. The grammar of the format is as
+ * follows:
+ *
+ * drm ::= 'drm=' option_list
+ * option_list ::= option [ ';' option_list ]
+ * option ::= 'device:' major
+ * | 'debug'
+ * | 'noctx'
+ * major ::= INTEGER
+ *
+ * Note that 's' contains option_list without the 'drm=' part.
+ *
+ * device=major,minor specifies the device number used for /dev/drm
+ * if major == 0 then the misc device is used
+ * if major == 0 and minor == 0 then dynamic misc allocation is used
+ * debug=on specifies that debugging messages will be printk'd
+ * debug=trace specifies that each function call will be logged via printk
+ * debug=off turns off all debugging options
+ *
+ */
+
+void drm_parse_options(char *s)
+{
+ char *h, *t, *n;
+
+ DRM_DEBUG("\"%s\"\n", s ?: "");
+ if (!s || !*s) return;
+
+ for (h = t = n = s; h && *h; h = n) {
+ for (; *t && *t != ';'; t++); /* find ; or \0 */
+ if (*t) n = t + 1; else n = NULL; /* remember next */
+ *t = '\0'; /* terminate */
+ drm_parse_option(h); /* parse */
+ }
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/ioctl.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/ioctl.c
new file mode 100644
index 000000000..55bdeedac
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/ioctl.c
@@ -0,0 +1,120 @@
+/* ioctl.c -- IOCTL processing for DRM -*- c -*-
+ * Created: Fri Jan 8 09:01:26 1999 by faith@precisioninsight.com
+ * Revised: Fri Aug 20 09:27:02 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ioctl.c,v 1.3 1999/08/30 13:05:00 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ioctl.c,v 1.1 1999/09/25 14:38:01 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+#include <sys/bus.h>
+#include <pci/pcivar.h>
+
+int
+drm_irq_busid(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_irq_busid_t id;
+ devclass_t pci;
+ device_t bus, dev;
+ device_t *kids;
+ int error, i, num_kids;
+
+ id = *(drm_irq_busid_t *) data;
+ pci = devclass_find("pci");
+ if (!pci)
+ return ENOENT;
+ bus = devclass_get_device(pci, id.busnum);
+ if (!bus)
+ return ENOENT;
+ error = device_get_children(bus, &kids, &num_kids);
+ if (error)
+ return error;
+
+ dev = 0;
+ for (i = 0; i < num_kids; i++) {
+ dev = kids[i];
+ if (pci_get_slot(dev) == id.devnum
+ && pci_get_function(dev) == id.funcnum)
+ break;
+ }
+
+ free(kids, M_TEMP);
+
+ if (i != num_kids)
+ id.irq = pci_get_irq(dev);
+ else
+ id.irq = 0;
+
+ DRM_DEBUG("%d:%d:%d => IRQ %d\n",
+ id.busnum, id.devnum, id.funcnum, id.irq);
+ *(drm_irq_busid_t *) data = id;
+
+ return 0;
+}
+
+int
+drm_getunique(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_unique_t u;
+ int error;
+
+ u = *(drm_unique_t *) data;
+ if (u.unique_len >= dev->unique_len) {
+ error = copyout(dev->unique, u.unique, dev->unique_len);
+ if (error)
+ return error;
+ }
+ u.unique_len = dev->unique_len;
+ *(drm_unique_t *) data = u;
+ return 0;
+}
+
+int
+drm_setunique(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_unique_t u;
+ int error;
+
+ if (dev->unique_len || dev->unique) return EBUSY;
+
+ u = *(drm_unique_t *) data;
+
+ dev->unique_len = u.unique_len;
+ dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER);
+ error = copyin(u.unique, dev->unique, dev->unique_len);
+ if (error)
+ return error;
+ dev->unique[dev->unique_len] = '\0';
+
+ dev->devname = drm_alloc(strlen(dev->name) + strlen(dev->unique) + 2,
+ DRM_MEM_DRIVER);
+ sprintf(dev->devname, "%s@%s", dev->name, dev->unique);
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/lists.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/lists.c
new file mode 100644
index 000000000..9f9b5f7ad
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/lists.c
@@ -0,0 +1,258 @@
+/* lists.c -- Buffer list handling routines -*- c -*-
+ * Created: Mon Apr 19 20:54:22 1999 by faith@precisioninsight.com
+ * Revised: Fri Aug 20 09:27:01 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/lists.c,v 1.3 1999/08/20 15:07:02 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/lists.c,v 1.1 1999/09/25 14:38:01 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+int drm_waitlist_create(drm_waitlist_t *bl, int count)
+{
+ DRM_DEBUG("%d\n", count);
+ if (bl->count) return EINVAL;
+
+ bl->count = count;
+ bl->bufs = drm_alloc((bl->count + 2) * sizeof(*bl->bufs),
+ DRM_MEM_BUFLISTS);
+ bl->rp = bl->bufs;
+ bl->wp = bl->bufs;
+ bl->end = &bl->bufs[bl->count+1];
+ simple_lock_init(&bl->write_lock);
+ simple_lock_init(&bl->read_lock);
+ return 0;
+}
+
+int drm_waitlist_destroy(drm_waitlist_t *bl)
+{
+ DRM_DEBUG("\n");
+ if (bl->rp != bl->wp) return EINVAL;
+ if (bl->bufs) drm_free(bl->bufs,
+ (bl->count + 2) * sizeof(*bl->bufs),
+ DRM_MEM_BUFLISTS);
+ bl->count = 0;
+ bl->bufs = NULL;
+ bl->rp = NULL;
+ bl->wp = NULL;
+ bl->end = NULL;
+ return 0;
+}
+
+int drm_waitlist_put(drm_waitlist_t *bl, drm_buf_t *buf)
+{
+ int left;
+ int s;
+
+ left = DRM_LEFTCOUNT(bl);
+ DRM_DEBUG("put %d (%d left, rp = %p, wp = %p)\n",
+ buf->idx, left, bl->rp, bl->wp);
+ if (!left) {
+ DRM_ERROR("Overflow while adding buffer %d from pid %d\n",
+ buf->idx, buf->pid);
+ return EINVAL;
+ }
+#if DRM_DMA_HISTOGRAM
+ getnanotime(&buf->time_queued);
+#endif
+ buf->list = DRM_LIST_WAIT;
+
+ simple_lock(&bl->write_lock);
+ s = spldrm();
+ *bl->wp = buf;
+ if (++bl->wp >= bl->end) bl->wp = bl->bufs;
+ splx(s);
+ simple_unlock(&bl->write_lock);
+
+ return 0;
+}
+
+drm_buf_t *drm_waitlist_get(drm_waitlist_t *bl)
+{
+ drm_buf_t *buf;
+ int s;
+
+ simple_lock(&bl->read_lock);
+ s = spldrm();
+ buf = *bl->rp;
+ if (bl->rp == bl->wp) {
+ splx(s);
+ simple_unlock(&bl->read_lock);
+ return NULL;
+ }
+ if (++bl->rp >= bl->end) bl->rp = bl->bufs;
+ splx(s);
+ simple_unlock(&bl->read_lock);
+
+ DRM_DEBUG("get %d\n", buf->idx);
+ return buf;
+}
+
+int drm_freelist_create(drm_freelist_t *bl, int count)
+{
+ DRM_DEBUG("\n");
+ atomic_set(&bl->count, 0);
+ bl->next = NULL;
+ bl->waiting = 0;
+ bl->low_mark = 0;
+ bl->high_mark = 0;
+ atomic_set(&bl->wfh, 0);
+ ++bl->initialized;
+ return 0;
+}
+
+int drm_freelist_destroy(drm_freelist_t *bl)
+{
+ DRM_DEBUG("\n");
+ atomic_set(&bl->count, 0);
+ bl->next = NULL;
+ return 0;
+}
+
+int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
+{
+ unsigned int old;
+ unsigned int new;
+ char failed;
+ int count = 0;
+ drm_device_dma_t *dma = dev->dma;
+
+ if (!dma) {
+ DRM_ERROR("No DMA support\n");
+ return 1;
+ }
+
+ if (buf->waiting || buf->pending || buf->list == DRM_LIST_FREE) {
+ DRM_ERROR("Freed buffer %d: w%d, p%d, l%d\n",
+ buf->idx, buf->waiting, buf->pending, buf->list);
+ }
+ DRM_DEBUG("%d, count = %d, wfh = %d, w%d, p%d\n",
+ buf->idx, atomic_read(&bl->count), atomic_read(&bl->wfh),
+ buf->waiting, buf->pending);
+ if (!bl) return 1;
+#if DRM_DMA_HISTOGRAM
+ getnanotime(&buf->time_freed);
+ drm_histogram_compute(dev, buf);
+#endif
+ buf->list = DRM_LIST_FREE;
+ do {
+ old = (unsigned long)bl->next;
+ buf->next = (void *)old;
+ new = (unsigned long)buf;
+ _DRM_CAS(&bl->next, old, new, failed);
+ if (++count > DRM_LOOPING_LIMIT) {
+ DRM_ERROR("Looping\n");
+ return 1;
+ }
+ } while (failed);
+ atomic_inc(&bl->count);
+ if (atomic_read(&bl->count) > dma->buf_count) {
+ DRM_ERROR("%d of %d buffers free after addition of %d\n",
+ atomic_read(&bl->count), dma->buf_count, buf->idx);
+ return 1;
+ }
+ /* Check for high water mark */
+ if (atomic_read(&bl->wfh) && atomic_read(&bl->count)>=bl->high_mark) {
+ atomic_set(&bl->wfh, 0);
+ if (bl->waiting)
+ wakeup(&bl->waiting);
+ }
+ return 0;
+}
+
+static drm_buf_t *drm_freelist_try(drm_freelist_t *bl)
+{
+ unsigned int old;
+ unsigned int new;
+ char failed;
+ drm_buf_t *buf;
+ int count = 0;
+
+ if (!bl) return NULL;
+
+ /* Get buffer */
+ do {
+ old = (unsigned int)bl->next;
+ if (!old) {
+ return NULL;
+ }
+ new = (unsigned long)bl->next->next;
+ _DRM_CAS(&bl->next, old, new, failed);
+ if (++count > DRM_LOOPING_LIMIT) {
+ DRM_ERROR("Looping\n");
+ return NULL;
+ }
+ } while (failed);
+ atomic_dec(&bl->count);
+
+ buf = (drm_buf_t *)old;
+ buf->next = NULL;
+ buf->list = DRM_LIST_NONE;
+ DRM_DEBUG("%d, count = %d, wfh = %d, w%d, p%d\n",
+ buf->idx, atomic_read(&bl->count), atomic_read(&bl->wfh),
+ buf->waiting, buf->pending);
+ if (buf->waiting || buf->pending) {
+ DRM_ERROR("Free buffer %d: w%d, p%d, l%d\n",
+ buf->idx, buf->waiting, buf->pending, buf->list);
+ }
+
+ return buf;
+}
+
+drm_buf_t *drm_freelist_get(drm_freelist_t *bl, int block)
+{
+ drm_buf_t *buf = NULL;
+ int error;
+
+ if (!bl || !bl->initialized) return NULL;
+
+ /* Check for low water mark */
+ if (atomic_read(&bl->count) <= bl->low_mark) /* Became low */
+ atomic_set(&bl->wfh, 1);
+ if (atomic_read(&bl->wfh)) {
+ DRM_DEBUG("Block = %d, count = %d, wfh = %d\n",
+ block, atomic_read(&bl->count),
+ atomic_read(&bl->wfh));
+ if (block) {
+ atomic_inc(&bl->waiting);
+ for (;;) {
+ if (!atomic_read(&bl->wfh)
+ && (buf = drm_freelist_try(bl))) break;
+ error = tsleep(&bl->waiting, PZERO|PCATCH,
+ "drmfg", 0);
+ if (error)
+ break;
+ }
+ atomic_dec(&bl->waiting);
+ }
+ return buf;
+ }
+
+ DRM_DEBUG("Count = %d, wfh = %d\n",
+ atomic_read(&bl->count), atomic_read(&bl->wfh));
+ return drm_freelist_try(bl);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/lock.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/lock.c
new file mode 100644
index 000000000..cd14a8825
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/lock.c
@@ -0,0 +1,220 @@
+/* lock.c -- IOCTLs for locking -*- c -*-
+ * Created: Tue Feb 2 08:37:54 1999 by faith@precisioninsight.com
+ * Revised: Tue Oct 12 08:51:06 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/lock.c,v 1.5 1999/08/30 13:05:00 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/lock.c,v 1.1 1999/09/25 14:38:01 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+int
+drm_block(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ DRM_DEBUG("\n");
+ return 0;
+}
+
+int
+drm_unblock(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ DRM_DEBUG("\n");
+ return 0;
+}
+
+int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
+{
+ unsigned int old;
+ unsigned int new;
+ char failed;
+
+ DRM_DEBUG("%d attempts\n", context);
+ do {
+ old = *lock;
+ if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
+ else new = context | _DRM_LOCK_HELD;
+ _DRM_CAS(lock, old, new, failed);
+ } while (failed);
+ if (_DRM_LOCKING_CONTEXT(old) == context) {
+ if (old & _DRM_LOCK_HELD) {
+ if (context != DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("%d holds heavyweight lock\n",
+ context);
+ }
+ return 0;
+ }
+ }
+ if (new == (context | _DRM_LOCK_HELD)) {
+ /* Have lock */
+ DRM_DEBUG("%d\n", context);
+ return 1;
+ }
+ DRM_DEBUG("%d unable to get lock held by %d\n",
+ context, _DRM_LOCKING_CONTEXT(old));
+ return 0;
+}
+
+/* This takes a lock forcibly and hands it to context. Should ONLY be used
+ inside *_unlock to give lock to kernel before calling *_dma_schedule. */
+int drm_lock_transfer(drm_device_t *dev,
+ __volatile__ unsigned int *lock, unsigned int context)
+{
+ unsigned int old;
+ unsigned int new;
+ char failed;
+
+ dev->lock.pid = 0;
+ do {
+ old = *lock;
+ new = context | _DRM_LOCK_HELD;
+ _DRM_CAS(lock, old, new, failed);
+ } while (failed);
+ DRM_DEBUG("%d => %d\n", _DRM_LOCKING_CONTEXT(old), context);
+ return 1;
+}
+
+int drm_lock_free(drm_device_t *dev,
+ __volatile__ unsigned int *lock, unsigned int context)
+{
+ unsigned int old;
+ unsigned int new;
+ char failed;
+ pid_t pid = dev->lock.pid;
+
+ DRM_DEBUG("%d\n", context);
+ dev->lock.pid = 0;
+ do {
+ old = *lock;
+ new = 0;
+ _DRM_CAS(lock, old, new, failed);
+ } while (failed);
+ if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
+ DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n",
+ context,
+ _DRM_LOCKING_CONTEXT(old),
+ pid);
+ return 1;
+ }
+ wakeup(&dev->lock.lock_queue);
+ return 0;
+}
+
+static int drm_flush_queue(drm_device_t *dev, int context)
+{
+ int ret = 0;
+ int error;
+ drm_queue_t *q = dev->queuelist[context];
+
+ DRM_DEBUG("\n");
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) > 1) {
+ atomic_inc(&q->block_write);
+ atomic_inc(&q->block_count);
+ error = tsleep(&q->flush_queue, PCATCH|PZERO, "drmfq", 0);
+ if (error)
+ return error;
+ atomic_dec(&q->block_count);
+ }
+ atomic_dec(&q->use_count);
+ atomic_inc(&q->total_flushed);
+
+ /* NOTE: block_write is still incremented!
+ Use drm_flush_unlock_queue to decrement. */
+ return ret;
+}
+
+static int drm_flush_unblock_queue(drm_device_t *dev, int context)
+{
+ drm_queue_t *q = dev->queuelist[context];
+
+ DRM_DEBUG("\n");
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) > 1) {
+ if (atomic_read(&q->block_write)) {
+ atomic_dec(&q->block_write);
+ wakeup(&q->write_queue);
+ }
+ }
+ atomic_dec(&q->use_count);
+ return 0;
+}
+
+int drm_flush_block_and_flush(drm_device_t *dev, int context,
+ drm_lock_flags_t flags)
+{
+ int ret = 0;
+ int i;
+
+ DRM_DEBUG("\n");
+
+ if (flags & _DRM_LOCK_FLUSH) {
+ ret = drm_flush_queue(dev, DRM_KERNEL_CONTEXT);
+ if (!ret) ret = drm_flush_queue(dev, context);
+ }
+ if (flags & _DRM_LOCK_FLUSH_ALL) {
+ for (i = 0; !ret && i < dev->queue_count; i++) {
+ ret = drm_flush_queue(dev, i);
+ }
+ }
+ return ret;
+}
+
+int drm_flush_unblock(drm_device_t *dev, int context, drm_lock_flags_t flags)
+{
+ int ret = 0;
+ int i;
+
+ DRM_DEBUG("\n");
+
+ if (flags & _DRM_LOCK_FLUSH) {
+ ret = drm_flush_unblock_queue(dev, DRM_KERNEL_CONTEXT);
+ if (!ret) ret = drm_flush_unblock_queue(dev, context);
+ }
+ if (flags & _DRM_LOCK_FLUSH_ALL) {
+ for (i = 0; !ret && i < dev->queue_count; i++) {
+ ret = drm_flush_unblock_queue(dev, i);
+ }
+ }
+
+ return ret;
+}
+
+int drm_finish(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ int ret = 0;
+ drm_lock_t lock;
+
+ DRM_DEBUG("\n");
+
+ lock = *(drm_lock_t *) data;
+ ret = drm_flush_block_and_flush(dev, lock.context, lock.flags);
+ drm_flush_unblock(dev, lock.context, lock.flags);
+ return ret;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/memory.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/memory.c
new file mode 100644
index 000000000..a8a936df0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/memory.c
@@ -0,0 +1,458 @@
+/* memory.c -- Memory management wrappers for DRM -*- c -*-
+ * Created: Thu Feb 4 14:00:34 1999 by faith@precisioninsight.com
+ * Revised: Fri Aug 20 13:04:33 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/memory.c,v 1.4 1999/08/20 20:00:53 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/memory.c,v 1.1 1999/09/25 14:38:02 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#ifdef DRM_AGP
+#include <sys/agpio.h>
+#endif
+
+MALLOC_DEFINE(M_DRM, "drm", "DRM Data Structures");
+
+typedef struct drm_mem_stats {
+ const char *name;
+ int succeed_count;
+ int free_count;
+ int fail_count;
+ unsigned long bytes_allocated;
+ unsigned long bytes_freed;
+} drm_mem_stats_t;
+
+#ifdef SMP
+static struct simplelock drm_mem_lock;
+#endif
+static unsigned long drm_ram_available = 0;
+static unsigned long drm_ram_used = 0;
+static drm_mem_stats_t drm_mem_stats[] = {
+ [DRM_MEM_DMA] = { "dmabufs" },
+ [DRM_MEM_SAREA] = { "sareas" },
+ [DRM_MEM_DRIVER] = { "driver" },
+ [DRM_MEM_MAGIC] = { "magic" },
+ [DRM_MEM_IOCTLS] = { "ioctltab" },
+ [DRM_MEM_MAPS] = { "maplist" },
+ [DRM_MEM_VMAS] = { "vmalist" },
+ [DRM_MEM_BUFS] = { "buflist" },
+ [DRM_MEM_SEGS] = { "seglist" },
+ [DRM_MEM_PAGES] = { "pagelist" },
+ [DRM_MEM_FILES] = { "files" },
+ [DRM_MEM_QUEUES] = { "queues" },
+ [DRM_MEM_CMDS] = { "commands" },
+ [DRM_MEM_MAPPINGS] = { "mappings" },
+ [DRM_MEM_BUFLISTS] = { "buflists" },
+ [DRM_MEM_AGPLISTS] = { "agplist" },
+ [DRM_MEM_TOTALAGP] = { "totalagp" },
+ [DRM_MEM_BOUNDAGP] = { "boundagp" },
+ [DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
+ { NULL, 0, } /* Last entry must be null */
+};
+
+void drm_mem_init(void)
+{
+ drm_mem_stats_t *mem;
+
+ for (mem = drm_mem_stats; mem->name; ++mem) {
+ mem->succeed_count = 0;
+ mem->free_count = 0;
+ mem->fail_count = 0;
+ mem->bytes_allocated = 0;
+ mem->bytes_freed = 0;
+ }
+
+ drm_ram_available = 0; /* si.totalram; */
+ drm_ram_used = 0;
+}
+
+/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
+
+static int _drm_mem_info SYSCTL_HANDLER_ARGS
+{
+ drm_mem_stats_t *pt;
+ char buf[128];
+ int error;
+
+ DRM_SYSCTL_PRINT(" total counts "
+ " | outstanding \n");
+ DRM_SYSCTL_PRINT("type alloc freed fail bytes freed"
+ " | allocs bytes\n\n");
+ DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu |\n",
+ "system", 0, 0, 0, drm_ram_available);
+ DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu |\n",
+ "locked", 0, 0, 0, drm_ram_used);
+ DRM_SYSCTL_PRINT("\n");
+ for (pt = drm_mem_stats; pt->name; pt++) {
+ DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
+ pt->name,
+ pt->succeed_count,
+ pt->free_count,
+ pt->fail_count,
+ pt->bytes_allocated,
+ pt->bytes_freed,
+ pt->succeed_count - pt->free_count,
+ (long)pt->bytes_allocated
+ - (long)pt->bytes_freed);
+ }
+ SYSCTL_OUT(req, "", 1);
+
+ return 0;
+}
+
+int drm_mem_info SYSCTL_HANDLER_ARGS
+{
+ int ret;
+
+ simple_lock(&drm_mem_lock);
+ ret = _drm_mem_info(oidp, arg1, arg2, req);
+ simple_unlock(&drm_mem_lock);
+ return ret;
+}
+
+void *drm_alloc(size_t size, int area)
+{
+ void *pt;
+
+ if (!size) {
+ DRM_MEM_ERROR(area, "Allocating 0 bytes\n");
+ return NULL;
+ }
+
+ if (!(pt = malloc(size, M_DRM, M_NOWAIT))) {
+ simple_lock(&drm_mem_lock);
+ ++drm_mem_stats[area].fail_count;
+ simple_unlock(&drm_mem_lock);
+ return NULL;
+ }
+ simple_lock(&drm_mem_lock);
+ ++drm_mem_stats[area].succeed_count;
+ drm_mem_stats[area].bytes_allocated += size;
+ simple_unlock(&drm_mem_lock);
+ return pt;
+}
+
+void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
+{
+ void *pt;
+
+ if (!(pt = drm_alloc(size, area))) return NULL;
+ if (oldpt && oldsize) {
+ memcpy(pt, oldpt, oldsize);
+ drm_free(oldpt, oldsize, area);
+ }
+ return pt;
+}
+
+char *drm_strdup(const char *s, int area)
+{
+ char *pt;
+ int length = s ? strlen(s) : 0;
+
+ if (!(pt = drm_alloc(length+1, area))) return NULL;
+ strcpy(pt, s);
+ return pt;
+}
+
+void drm_strfree(char *s, int area)
+{
+ unsigned int size;
+
+ if (!s) return;
+
+ size = 1 + (s ? strlen(s) : 0);
+ drm_free((void *)s, size, area);
+}
+
+void drm_free(void *pt, size_t size, int area)
+{
+ int alloc_count;
+ int free_count;
+
+ if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
+ else free(pt, M_DRM);
+ simple_lock(&drm_mem_lock);
+ drm_mem_stats[area].bytes_freed += size;
+ free_count = ++drm_mem_stats[area].free_count;
+ alloc_count = drm_mem_stats[area].succeed_count;
+ simple_unlock(&drm_mem_lock);
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+}
+
+unsigned long drm_alloc_pages(int order, int area)
+{
+ vm_offset_t address;
+ unsigned long bytes = PAGE_SIZE << order;
+ unsigned long addr;
+ unsigned int sz;
+
+ simple_lock(&drm_mem_lock);
+ if (drm_ram_used > +(DRM_RAM_PERCENT * drm_ram_available) / 100) {
+ simple_unlock(&drm_mem_lock);
+ return 0;
+ }
+ simple_unlock(&drm_mem_lock);
+
+ address = (vm_offset_t) contigmalloc(1<<order, M_DRM, M_WAITOK, 0, ~0, 1, 0);
+ if (!address) {
+ simple_lock(&drm_mem_lock);
+ ++drm_mem_stats[area].fail_count;
+ simple_unlock(&drm_mem_lock);
+ return 0;
+ }
+ simple_lock(&drm_mem_lock);
+ ++drm_mem_stats[area].succeed_count;
+ drm_mem_stats[area].bytes_allocated += bytes;
+ drm_ram_used += bytes;
+ simple_unlock(&drm_mem_lock);
+
+
+ /* Zero outside the lock */
+ memset((void *)address, 0, bytes);
+
+ /* Reserve */
+ for (addr = address, sz = bytes;
+ sz > 0;
+ addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+ /* mem_map_reserve(MAP_NR(addr));*/
+ }
+
+ return address;
+}
+
+void drm_free_pages(unsigned long address, int order, int area)
+{
+ unsigned long bytes = PAGE_SIZE << order;
+ int alloc_count;
+ int free_count;
+ unsigned long addr;
+ unsigned int sz;
+
+ if (!address) {
+ DRM_MEM_ERROR(area, "Attempt to free address 0\n");
+ } else {
+ /* Unreserve */
+ for (addr = address, sz = bytes;
+ sz > 0;
+ addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+ /* mem_map_unreserve(MAP_NR(addr));*/
+ }
+ contigfree((void *) address, bytes, M_DRM);
+ }
+
+ simple_lock(&drm_mem_lock);
+ free_count = ++drm_mem_stats[area].free_count;
+ alloc_count = drm_mem_stats[area].succeed_count;
+ drm_mem_stats[area].bytes_freed += bytes;
+ drm_ram_used -= bytes;
+ simple_unlock(&drm_mem_lock);
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(area,
+ "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+}
+
+void *drm_ioremap(unsigned long offset, unsigned long size)
+{
+ void *pt;
+
+ if (!size) {
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Mapping 0 bytes at 0x%08lx\n", offset);
+ return NULL;
+ }
+
+ if (!(pt = pmap_mapdev(offset, size))) {
+ simple_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count;
+ simple_unlock(&drm_mem_lock);
+ return NULL;
+ }
+ simple_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
+ drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size;
+ simple_unlock(&drm_mem_lock);
+ return pt;
+}
+
+void drm_ioremapfree(void *pt, unsigned long size)
+{
+ int alloc_count;
+ int free_count;
+
+ if (!pt)
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Attempt to free NULL pointer\n");
+ else
+ pmap_unmapdev((vm_offset_t) pt, size);
+
+ simple_lock(&drm_mem_lock);
+ drm_mem_stats[DRM_MEM_MAPPINGS].bytes_freed += size;
+ free_count = ++drm_mem_stats[DRM_MEM_MAPPINGS].free_count;
+ alloc_count = drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
+ simple_unlock(&drm_mem_lock);
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+}
+
+#ifdef DRM_AGP
+void *drm_alloc_agp(int pages, u_int32_t type)
+{
+ device_t dev = agp_find_device();
+ void *handle;
+
+ if (!dev)
+ return NULL;
+
+ if (!pages) {
+ DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Allocating 0 pages\n");
+ return NULL;
+ }
+
+ if ((handle = agp_alloc_memory(dev, type, pages << AGP_PAGE_SHIFT))) {
+ simple_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count;
+ drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated
+ += pages << PAGE_SHIFT;
+ simple_unlock(&drm_mem_lock);
+ return handle;
+ }
+ simple_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_TOTALAGP].fail_count;
+ simple_unlock(&drm_mem_lock);
+ return NULL;
+}
+
+int drm_free_agp(void *handle, int pages)
+{
+ device_t dev = agp_find_device();
+ int alloc_count;
+ int free_count;
+ int retval = EINVAL;
+
+ if (!dev)
+ return EINVAL;
+
+ if (!handle) {
+ DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
+ "Attempt to free NULL AGP handle\n");
+ return retval;
+ }
+
+ agp_free_memory(dev, handle);
+ simple_lock(&drm_mem_lock);
+ free_count = ++drm_mem_stats[DRM_MEM_TOTALAGP].free_count;
+ alloc_count = drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count;
+ drm_mem_stats[DRM_MEM_TOTALAGP].bytes_freed
+ += pages << PAGE_SHIFT;
+ simple_unlock(&drm_mem_lock);
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
+ "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+ return 0;
+}
+
+int drm_bind_agp(void *handle, unsigned int start)
+{
+ device_t dev = agp_find_device();
+ int retcode = EINVAL;
+ struct agp_memory_info info;
+
+ DRM_DEBUG("drm_bind_agp called\n");
+
+ if (!dev)
+ return EINVAL;
+
+ if (!handle) {
+ DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
+ "Attempt to bind NULL AGP handle\n");
+ return retcode;
+ }
+
+ if (!(retcode = agp_bind_memory(dev, handle,
+ start << AGP_PAGE_SHIFT))) {
+ simple_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count;
+ agp_memory_info(dev, handle, &info);
+ drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated
+ += info.ami_size;
+ simple_unlock(&drm_mem_lock);
+ DRM_DEBUG("drm_agp.bind_memory: retcode %d\n", retcode);
+ return retcode;
+ }
+ simple_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_BOUNDAGP].fail_count;
+ simple_unlock(&drm_mem_lock);
+ return retcode;
+}
+
+int drm_unbind_agp(void *handle)
+{
+ device_t dev = agp_find_device();
+ int alloc_count;
+ int free_count;
+ int retcode = EINVAL;
+ struct agp_memory_info info;
+
+ if (!dev)
+ return EINVAL;
+
+ if (!handle) {
+ DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
+ "Attempt to unbind NULL AGP handle\n");
+ return retcode;
+ }
+
+
+ agp_memory_info(dev, handle, &info);
+ if ((retcode = agp_unbind_memory(dev, handle)))
+ return retcode;
+ simple_lock(&drm_mem_lock);
+ free_count = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count;
+ alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count;
+ drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed += info.ami_size;
+ simple_unlock(&drm_mem_lock);
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
+ "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+ return retcode;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/proc.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/proc.c
new file mode 100644
index 000000000..12168aa3d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/proc.c
@@ -0,0 +1,568 @@
+/* proc.c -- /proc support for DRM -*- c -*-
+ * Created: Mon Jan 11 09:48:47 1999 by faith@precisioninsight.com
+ * Revised: Fri Aug 20 11:31:48 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c,v 1.4 1999/08/20 15:36:46 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c,v 1.1 1999/09/25 14:38:02 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+static struct proc_dir_entry *drm_root = NULL;
+static struct proc_dir_entry *drm_dev_root = NULL;
+static char drm_slot_name[64];
+
+static int drm_name_info(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data);
+static int drm_vm_info(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data);
+static int drm_clients_info(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data);
+static int drm_queues_info(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data);
+static int drm_bufs_info(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data);
+#if DRM_DEBUG_CODE
+static int drm_vma_info(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data);
+#endif
+#if DRM_DMA_HISTOGRAM
+static int drm_histo_info(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data);
+#endif
+
+struct drm_proc_list {
+ const char *name;
+ int (*f)(char *, char **, off_t, int, int *, void *);
+} drm_proc_list[] = {
+ { "name", drm_name_info },
+ { "mem", drm_mem_info },
+ { "vm", drm_vm_info },
+ { "clients", drm_clients_info },
+ { "queues", drm_queues_info },
+ { "bufs", drm_bufs_info },
+#if DRM_DEBUG_CODE
+ { "vma", drm_vma_info },
+#endif
+#if DRM_DMA_HISTOGRAM
+ { "histo", drm_histo_info },
+#endif
+};
+#define DRM_PROC_ENTRIES (sizeof(drm_proc_list)/sizeof(drm_proc_list[0]))
+
+int drm_proc_init(drm_device_t *dev)
+{
+ struct proc_dir_entry *ent;
+ int i, j;
+
+ drm_root = create_proc_entry("graphics", S_IFDIR, NULL);
+ if (!drm_root) {
+ DRM_ERROR("Cannot create /proc/graphics\n");
+ return -1;
+ }
+
+ /* Instead of doing this search, we should
+ add some global support for /proc/graphics. */
+ for (i = 0; i < 8; i++) {
+ sprintf(drm_slot_name, "graphics/%d", i);
+ drm_dev_root = create_proc_entry(drm_slot_name, S_IFDIR, NULL);
+ if (!drm_dev_root) {
+ DRM_ERROR("Cannot create /proc/%s\n", drm_slot_name);
+ remove_proc_entry("graphics", NULL);
+ }
+ if (drm_dev_root->nlink == 2) break;
+ drm_dev_root = NULL;
+ }
+ if (!drm_dev_root) {
+ DRM_ERROR("Cannot find slot in /proc/graphics\n");
+ return -1;
+ }
+
+ for (i = 0; i < DRM_PROC_ENTRIES; i++) {
+ ent = create_proc_entry(drm_proc_list[i].name,
+ S_IFREG|S_IRUGO, drm_dev_root);
+ if (!ent) {
+ DRM_ERROR("Cannot create /proc/%s/%s\n",
+ drm_slot_name, drm_proc_list[i].name);
+ for (j = 0; j < i; j++)
+ remove_proc_entry(drm_proc_list[i].name,
+ drm_dev_root);
+ remove_proc_entry(drm_slot_name, NULL);
+ remove_proc_entry("graphics", NULL);
+ return -1;
+ }
+ ent->read_proc = drm_proc_list[i].f;
+ ent->data = dev;
+ }
+
+ return 0;
+}
+
+
+int drm_proc_cleanup(void)
+{
+ int i;
+
+ if (drm_root) {
+ if (drm_dev_root) {
+ for (i = 0; i < DRM_PROC_ENTRIES; i++) {
+ remove_proc_entry(drm_proc_list[i].name,
+ drm_dev_root);
+ }
+ remove_proc_entry(drm_slot_name, NULL);
+ }
+ remove_proc_entry("graphics", NULL);
+ remove_proc_entry(DRM_NAME, NULL);
+ }
+ drm_root = drm_dev_root = NULL;
+ return 0;
+}
+
+static int drm_name_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+
+ if (offset > 0) return 0; /* no partial requests */
+ len = 0;
+ *eof = 1;
+
+ if (dev->unique) {
+ DRM_PROC_PRINT("%s 0x%x %s\n",
+ dev->name, dev->device, dev->unique);
+ } else {
+ DRM_PROC_PRINT("%s 0x%x\n", dev->name, dev->device);
+ }
+ return len;
+}
+
+static int _drm_vm_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ drm_map_t *map;
+ const char *types[] = { "FB", "REG", "SHM" };
+ const char *type;
+ int i;
+
+ if (offset > 0) return 0; /* no partial requests */
+ len = 0;
+ *eof = 1;
+ DRM_PROC_PRINT("slot offset size type flags "
+ "address mtrr\n\n");
+ for (i = 0; i < dev->map_count; i++) {
+ map = dev->maplist[i];
+ if (map->type < 0 || map->type > 2) type = "??";
+ else type = types[map->type];
+ DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
+ i,
+ map->offset,
+ map->size,
+ type,
+ map->flags,
+ (unsigned long)map->handle);
+ if (map->mtrr < 0) {
+ DRM_PROC_PRINT("none\n");
+ } else {
+ DRM_PROC_PRINT("%4d\n", map->mtrr);
+ }
+ }
+
+ return len;
+}
+
+static int drm_vm_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ int ret;
+
+ down(&dev->struct_sem);
+ ret = _drm_vm_info(buf, start, offset, len, eof, data);
+ up(&dev->struct_sem);
+ return ret;
+}
+
+
+static int _drm_queues_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ int i;
+ drm_queue_t *q;
+
+ if (offset > 0) return 0; /* no partial requests */
+ len = 0;
+ *eof = 1;
+ DRM_PROC_PRINT(" ctx/flags use fin"
+ " blk/rw/rwf wait flushed queued"
+ " locks\n\n");
+ for (i = 0; i < dev->queue_count; i++) {
+ q = dev->queuelist[i];
+ atomic_inc(&q->use_count);
+ DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
+ "%5d/0x%03x %5d %5d"
+ " %5d/%c%c/%c%c%c %5d %10d %10d %10d\n",
+ i,
+ q->flags,
+ atomic_read(&q->use_count),
+ atomic_read(&q->finalization),
+ atomic_read(&q->block_count),
+ atomic_read(&q->block_read) ? 'r' : '-',
+ atomic_read(&q->block_write) ? 'w' : '-',
+ waitqueue_active(&q->read_queue) ? 'r':'-',
+ waitqueue_active(&q->write_queue) ? 'w':'-',
+ waitqueue_active(&q->flush_queue) ? 'f':'-',
+ DRM_BUFCOUNT(&q->waitlist),
+ atomic_read(&q->total_flushed),
+ atomic_read(&q->total_queued),
+ atomic_read(&q->total_locks));
+ atomic_dec(&q->use_count);
+ }
+
+ return len;
+}
+
+static int drm_queues_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ int ret;
+
+ down(&dev->struct_sem);
+ ret = _drm_queues_info(buf, start, offset, len, eof, data);
+ up(&dev->struct_sem);
+ return ret;
+}
+
+/* drm_bufs_info is called whenever a process reads
+ /dev/drm/<dev>/bufs. */
+
+static int _drm_bufs_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ drm_device_dma_t *dma = dev->dma;
+ int i;
+
+ if (!dma) return 0;
+ if (offset > 0) return 0; /* no partial requests */
+ len = 0;
+ *eof = 1;
+ DRM_PROC_PRINT(" o size count free segs pages kB\n\n");
+ for (i = 0; i <= DRM_MAX_ORDER; i++) {
+ if (dma->bufs[i].buf_count)
+ DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n",
+ i,
+ dma->bufs[i].buf_size,
+ dma->bufs[i].buf_count,
+ atomic_read(&dma->bufs[i]
+ .freelist.count),
+ dma->bufs[i].seg_count,
+ dma->bufs[i].seg_count
+ *(1 << dma->bufs[i].page_order),
+ (dma->bufs[i].seg_count
+ * (1 << dma->bufs[i].page_order))
+ * PAGE_SIZE / 1024);
+ }
+ DRM_PROC_PRINT("\n");
+ for (i = 0; i < dma->buf_count; i++) {
+ if (i && !(i%32)) DRM_PROC_PRINT("\n");
+ DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
+ }
+ DRM_PROC_PRINT("\n");
+
+ return len;
+}
+
+static int drm_bufs_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ int ret;
+
+ down(&dev->struct_sem);
+ ret = _drm_bufs_info(buf, start, offset, len, eof, data);
+ up(&dev->struct_sem);
+ return ret;
+}
+
+
+static int _drm_clients_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ drm_file_t *priv;
+
+ if (offset > 0) return 0; /* no partial requests */
+ len = 0;
+ *eof = 1;
+ DRM_PROC_PRINT("a dev pid uid magic ioctls\n\n");
+ for (priv = dev->file_first; priv; priv = priv->next) {
+ DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
+ priv->authenticated ? 'y' : 'n',
+ priv->minor,
+ priv->pid,
+ priv->uid,
+ priv->magic,
+ priv->ioctl_count);
+ }
+
+ return len;
+}
+
+static int drm_clients_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ int ret;
+
+ down(&dev->struct_sem);
+ ret = _drm_clients_info(buf, start, offset, len, eof, data);
+ up(&dev->struct_sem);
+ return ret;
+}
+
+#if DRM_DEBUG_CODE
+
+static int _drm_vma_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ drm_vma_entry_t *pt;
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
+ unsigned long i;
+ struct vm_area_struct *vma;
+ unsigned long address;
+#if defined(__i386__)
+ unsigned int pgprot;
+#endif
+
+ if (offset > 0) return 0; /* no partial requests */
+ len = 0;
+ *eof = 1;
+ DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
+ atomic_read(&dev->vma_count),
+ high_memory, virt_to_phys(high_memory));
+ for (pt = dev->vmalist; pt; pt = pt->next) {
+ if (!(vma = pt->vma)) continue;
+ DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
+ pt->pid,
+ vma->vm_start,
+ vma->vm_end,
+ vma->vm_flags & VM_READ ? 'r' : '-',
+ vma->vm_flags & VM_WRITE ? 'w' : '-',
+ vma->vm_flags & VM_EXEC ? 'x' : '-',
+ vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
+ vma->vm_flags & VM_LOCKED ? 'l' : '-',
+ vma->vm_flags & VM_IO ? 'i' : '-',
+ vma->vm_offset );
+#if defined(__i386__)
+ pgprot = pgprot_val(vma->vm_page_prot);
+ DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
+ pgprot & _PAGE_PRESENT ? 'p' : '-',
+ pgprot & _PAGE_RW ? 'w' : 'r',
+ pgprot & _PAGE_USER ? 'u' : 's',
+ pgprot & _PAGE_PWT ? 't' : 'b',
+ pgprot & _PAGE_PCD ? 'u' : 'c',
+ pgprot & _PAGE_ACCESSED ? 'a' : '-',
+ pgprot & _PAGE_DIRTY ? 'd' : '-',
+ pgprot & _PAGE_4M ? 'm' : 'k',
+ pgprot & _PAGE_GLOBAL ? 'g' : 'l' );
+#endif
+ DRM_PROC_PRINT("\n");
+ for (i = vma->vm_start; i < vma->vm_end; i += PAGE_SIZE) {
+ pgd = pgd_offset(vma->vm_mm, i);
+ pmd = pmd_offset(pgd, i);
+ pte = pte_offset(pmd, i);
+ if (pte_present(*pte)) {
+ address = __pa(pte_page(*pte))
+ + (i & (PAGE_SIZE-1));
+ DRM_PROC_PRINT(" 0x%08lx -> 0x%08lx"
+ " %c%c%c%c%c\n",
+ i,
+ address,
+ pte_read(*pte) ? 'r' : '-',
+ pte_write(*pte) ? 'w' : '-',
+ pte_exec(*pte) ? 'x' : '-',
+ pte_dirty(*pte) ? 'd' : '-',
+ pte_young(*pte) ? 'a' : '-' );
+ } else {
+ DRM_PROC_PRINT(" 0x%08lx\n", i);
+ }
+ }
+ }
+
+ return len;
+}
+
+static int drm_vma_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ int ret;
+
+ down(&dev->struct_sem);
+ ret = _drm_vma_info(buf, start, offset, len, eof, data);
+ up(&dev->struct_sem);
+ return ret;
+}
+#endif
+
+
+#if DRM_DMA_HISTOGRAM
+static int _drm_histo_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ drm_device_dma_t *dma = dev->dma;
+ int i;
+ unsigned long slot_value = DRM_DMA_HISTOGRAM_INITIAL;
+ unsigned long prev_value = 0;
+ drm_buf_t *buffer;
+
+ if (offset > 0) return 0; /* no partial requests */
+ len = 0;
+ *eof = 1;
+
+ DRM_PROC_PRINT("general statistics:\n");
+ DRM_PROC_PRINT("total %10u\n", atomic_read(&dev->histo.total));
+ DRM_PROC_PRINT("open %10u\n", atomic_read(&dev->total_open));
+ DRM_PROC_PRINT("close %10u\n", atomic_read(&dev->total_close));
+ DRM_PROC_PRINT("ioctl %10u\n", atomic_read(&dev->total_ioctl));
+ DRM_PROC_PRINT("irq %10u\n", atomic_read(&dev->total_irq));
+ DRM_PROC_PRINT("ctx %10u\n", atomic_read(&dev->total_ctx));
+
+ DRM_PROC_PRINT("\nlock statistics:\n");
+ DRM_PROC_PRINT("locks %10u\n", atomic_read(&dev->total_locks));
+ DRM_PROC_PRINT("unlocks %10u\n", atomic_read(&dev->total_unlocks));
+ DRM_PROC_PRINT("contends %10u\n", atomic_read(&dev->total_contends));
+ DRM_PROC_PRINT("sleeps %10u\n", atomic_read(&dev->total_sleeps));
+
+
+ if (dma) {
+ DRM_PROC_PRINT("\ndma statistics:\n");
+ DRM_PROC_PRINT("prio %10u\n",
+ atomic_read(&dma->total_prio));
+ DRM_PROC_PRINT("bytes %10u\n",
+ atomic_read(&dma->total_bytes));
+ DRM_PROC_PRINT("dmas %10u\n",
+ atomic_read(&dma->total_dmas));
+ DRM_PROC_PRINT("missed:\n");
+ DRM_PROC_PRINT(" dma %10u\n",
+ atomic_read(&dma->total_missed_dma));
+ DRM_PROC_PRINT(" lock %10u\n",
+ atomic_read(&dma->total_missed_lock));
+ DRM_PROC_PRINT(" free %10u\n",
+ atomic_read(&dma->total_missed_free));
+ DRM_PROC_PRINT(" sched %10u\n",
+ atomic_read(&dma->total_missed_sched));
+ DRM_PROC_PRINT("tried %10u\n",
+ atomic_read(&dma->total_tried));
+ DRM_PROC_PRINT("hit %10u\n",
+ atomic_read(&dma->total_hit));
+ DRM_PROC_PRINT("lost %10u\n",
+ atomic_read(&dma->total_lost));
+
+ buffer = dma->next_buffer;
+ if (buffer) {
+ DRM_PROC_PRINT("next_buffer %7d\n", buffer->idx);
+ } else {
+ DRM_PROC_PRINT("next_buffer none\n");
+ }
+ buffer = dma->this_buffer;
+ if (buffer) {
+ DRM_PROC_PRINT("this_buffer %7d\n", buffer->idx);
+ } else {
+ DRM_PROC_PRINT("this_buffer none\n");
+ }
+ }
+
+
+ DRM_PROC_PRINT("\nvalues:\n");
+ if (dev->lock.hw_lock) {
+ DRM_PROC_PRINT("lock 0x%08x\n",
+ dev->lock.hw_lock->lock);
+ } else {
+ DRM_PROC_PRINT("lock none\n");
+ }
+ DRM_PROC_PRINT("context_flag 0x%08x\n", dev->context_flag);
+ DRM_PROC_PRINT("interrupt_flag 0x%08x\n", dev->interrupt_flag);
+ DRM_PROC_PRINT("dma_flag 0x%08x\n", dev->dma_flag);
+
+ DRM_PROC_PRINT("queue_count %10d\n", dev->queue_count);
+ DRM_PROC_PRINT("last_context %10d\n", dev->last_context);
+ DRM_PROC_PRINT("last_switch %10lu\n", dev->last_switch);
+ DRM_PROC_PRINT("last_checked %10d\n", dev->last_checked);
+
+
+ DRM_PROC_PRINT("\n q2d d2c c2f"
+ " q2c q2f dma sch"
+ " ctx lacq lhld\n\n");
+ for (i = 0; i < DRM_DMA_HISTOGRAM_SLOTS; i++) {
+ DRM_PROC_PRINT("%s %10lu %10u %10u %10u %10u %10u"
+ " %10u %10u %10u %10u %10u\n",
+ i == DRM_DMA_HISTOGRAM_SLOTS - 1 ? ">=" : "< ",
+ i == DRM_DMA_HISTOGRAM_SLOTS - 1
+ ? prev_value : slot_value ,
+
+ atomic_read(&dev->histo
+ .queued_to_dispatched[i]),
+ atomic_read(&dev->histo
+ .dispatched_to_completed[i]),
+ atomic_read(&dev->histo
+ .completed_to_freed[i]),
+
+ atomic_read(&dev->histo
+ .queued_to_completed[i]),
+ atomic_read(&dev->histo
+ .queued_to_freed[i]),
+ atomic_read(&dev->histo.dma[i]),
+ atomic_read(&dev->histo.schedule[i]),
+ atomic_read(&dev->histo.ctx[i]),
+ atomic_read(&dev->histo.lacq[i]),
+ atomic_read(&dev->histo.lhld[i]));
+ prev_value = slot_value;
+ slot_value = DRM_DMA_HISTOGRAM_NEXT(slot_value);
+ }
+ return len;
+}
+
+static int drm_histo_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ int ret;
+
+ down(&dev->struct_sem);
+ ret = _drm_histo_info(buf, start, offset, len, eof, data);
+ up(&dev->struct_sem);
+ return ret;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/sysctl.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/sysctl.c
new file mode 100644
index 000000000..7c736abff
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/sysctl.c
@@ -0,0 +1,554 @@
+/* proc.c -- /proc support for DRM -*- c -*-
+ * Created: Mon Jan 11 09:48:47 1999 by faith@precisioninsight.com
+ * Revised: Fri Aug 20 11:31:48 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI$
+ * $XFree86$
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+#include <sys/sysctl.h>
+
+SYSCTL_NODE(_hw, OID_AUTO, dri, CTLFLAG_RW, 0, "DRI Graphics");
+
+static int drm_name_info SYSCTL_HANDLER_ARGS;
+static int drm_vm_info SYSCTL_HANDLER_ARGS;
+static int drm_clients_info SYSCTL_HANDLER_ARGS;
+static int drm_queues_info SYSCTL_HANDLER_ARGS;
+static int drm_bufs_info SYSCTL_HANDLER_ARGS;
+#if DRM_DEBUG_CODExx
+static int drm_vma_info SYSCTL_HANDLER_ARGS;
+#endif
+#if DRM_DMA_HISTOGRAM
+static int drm_histo_info SYSCTL_HANDLER_ARGS;
+#endif
+
+struct drm_sysctl_list {
+ const char *name;
+ int (*f) SYSCTL_HANDLER_ARGS;
+} drm_sysctl_list[] = {
+ { "name", drm_name_info },
+ { "mem", drm_mem_info },
+ { "vm", drm_vm_info },
+ { "clients", drm_clients_info },
+ { "queues", drm_queues_info },
+ { "bufs", drm_bufs_info },
+#if DRM_DEBUG_CODExx
+ { "vma", drm_vma_info },
+#endif
+#if DRM_DMA_HISTOGRAM
+ { "histo", drm_histo_info },
+#endif
+};
+#define DRM_SYSCTL_ENTRIES (sizeof(drm_sysctl_list)/sizeof(drm_sysctl_list[0]))
+
+struct drm_sysctl_info {
+ struct sysctl_oid oids[DRM_SYSCTL_ENTRIES + 1];
+ struct sysctl_oid_list list;
+ char name[2];
+};
+
+int drm_sysctl_init(drm_device_t *dev)
+{
+ struct drm_sysctl_info *info;
+ struct sysctl_oid *oid;
+ struct sysctl_oid *top;
+ int i;
+
+ /* Find the next free slot under hw.graphics */
+ i = 0;
+ SLIST_FOREACH(oid, &sysctl__hw_dri_children, oid_link) {
+ if (i <= oid->oid_arg2)
+ i = oid->oid_arg2 + 1;
+ }
+
+ info = drm_alloc(sizeof *info, DRM_MEM_DRIVER);
+ dev->sysctl = info;
+
+ /* Construct the node under hw.graphics */
+ info->name[0] = '0' + i;
+ info->name[1] = 0;
+ oid = &info->oids[DRM_SYSCTL_ENTRIES];
+ bzero(oid, sizeof(*oid));
+ oid->oid_parent = &sysctl__hw_dri_children;
+ oid->oid_number = OID_AUTO;
+ oid->oid_kind = CTLTYPE_NODE | CTLFLAG_RW;
+ oid->oid_arg1 = &info->list;
+ oid->oid_arg2 = i;
+ oid->oid_name = info->name;
+ oid->oid_handler = 0;
+ oid->oid_fmt = "N";
+ SLIST_INIT(&info->list);
+ sysctl_register_oid(oid);
+ top = oid;
+
+ for (i = 0; i < DRM_SYSCTL_ENTRIES; i++) {
+ oid = &info->oids[i];
+ bzero(oid, sizeof(*oid));
+ oid->oid_parent = top->oid_arg1;
+ oid->oid_number = OID_AUTO;
+ oid->oid_kind = CTLTYPE_INT | CTLFLAG_RD;
+ oid->oid_arg1 = dev;
+ oid->oid_arg2 = 0;
+ oid->oid_name = drm_sysctl_list[i].name;
+ oid->oid_handler = drm_sysctl_list[i].f;
+ oid->oid_fmt = "A";
+ sysctl_register_oid(oid);
+ }
+
+ return 0;
+}
+
+int drm_sysctl_cleanup(drm_device_t *dev)
+{
+ int i;
+
+ DRM_DEBUG("dev->sysctl=%p\n", dev->sysctl);
+ for (i = 0; i < DRM_SYSCTL_ENTRIES + 1; i++)
+ sysctl_unregister_oid(&dev->sysctl->oids[i]);
+
+ drm_free(dev->sysctl, sizeof *dev->sysctl, DRM_MEM_DRIVER);
+ dev->sysctl = NULL;
+
+ return 0;
+}
+
+static int drm_name_info SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ char buf[128];
+ int error;
+
+ if (dev->unique) {
+ DRM_SYSCTL_PRINT("%s 0x%x %s\n",
+ dev->name, dev2udev(dev->devnode), dev->unique);
+ } else {
+ DRM_SYSCTL_PRINT("%s 0x%x\n", dev->name, dev2udev(dev->devnode));
+ }
+
+ SYSCTL_OUT(req, "", 1);
+
+ return 0;
+}
+
+static int _drm_vm_info SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ drm_map_t *map;
+ const char *types[] = { "FB", "REG", "SHM" };
+ const char *type;
+ int i;
+ char buf[128];
+ int error;
+
+ DRM_SYSCTL_PRINT("slot offset size type flags "
+ "address mtrr\n\n");
+ error = SYSCTL_OUT(req, buf, strlen(buf));
+ if (error) return error;
+
+ for (i = 0; i < dev->map_count; i++) {
+ map = dev->maplist[i];
+ if (map->type < 0 || map->type > 2) type = "??";
+ else type = types[map->type];
+ DRM_SYSCTL_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
+ i,
+ map->offset,
+ map->size,
+ type,
+ map->flags,
+ (unsigned long)map->handle);
+ if (map->mtrr < 0) {
+ DRM_SYSCTL_PRINT("none\n");
+ } else {
+ DRM_SYSCTL_PRINT("%4d\n", map->mtrr);
+ }
+ }
+ SYSCTL_OUT(req, "", 1);
+
+ return 0;
+}
+
+static int drm_vm_info SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ int ret;
+
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc);
+ ret = _drm_vm_info(oidp, arg1, arg2, req);
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+
+ return ret;
+}
+
+
+static int _drm_queues_info SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ int i;
+ drm_queue_t *q;
+ char buf[128];
+ int error;
+
+ DRM_SYSCTL_PRINT(" ctx/flags use fin"
+ " blk/rw/rwf wait flushed queued"
+ " locks\n\n");
+ for (i = 0; i < dev->queue_count; i++) {
+ q = dev->queuelist[i];
+ atomic_inc(&q->use_count);
+ DRM_SYSCTL_PRINT_RET(atomic_dec(&q->use_count),
+ "%5d/0x%03x %5d %5d"
+ " %5d/%c%c/%c%c%c %5d %10d %10d %10d\n",
+ i,
+ q->flags,
+ atomic_read(&q->use_count),
+ atomic_read(&q->finalization),
+ atomic_read(&q->block_count),
+ atomic_read(&q->block_read) ? 'r' : '-',
+ atomic_read(&q->block_write) ? 'w' : '-',
+ q->read_queue ? 'r':'-',
+ q->write_queue ? 'w':'-',
+ q->flush_queue ? 'f':'-',
+ DRM_BUFCOUNT(&q->waitlist),
+ atomic_read(&q->total_flushed),
+ atomic_read(&q->total_queued),
+ atomic_read(&q->total_locks));
+ atomic_dec(&q->use_count);
+ }
+
+ SYSCTL_OUT(req, "", 1);
+ return 0;
+}
+
+static int drm_queues_info SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ int ret;
+
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc);
+ ret = _drm_queues_info(oidp, arg1, arg2, req);
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+ return ret;
+}
+
+/* drm_bufs_info is called whenever a process reads
+ hw.dri.0.bufs. */
+
+static int _drm_bufs_info SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ drm_device_dma_t *dma = dev->dma;
+ int i;
+ char buf[128];
+ int error;
+
+ if (!dma) return 0;
+ DRM_SYSCTL_PRINT(" o size count free segs pages kB\n\n");
+ for (i = 0; i <= DRM_MAX_ORDER; i++) {
+ if (dma->bufs[i].buf_count)
+ DRM_SYSCTL_PRINT("%2d %8d %5d %5d %5d %5d %5d\n",
+ i,
+ dma->bufs[i].buf_size,
+ dma->bufs[i].buf_count,
+ atomic_read(&dma->bufs[i]
+ .freelist.count),
+ dma->bufs[i].seg_count,
+ dma->bufs[i].seg_count
+ *(1 << dma->bufs[i].page_order),
+ (dma->bufs[i].seg_count
+ * (1 << dma->bufs[i].page_order))
+ * PAGE_SIZE / 1024);
+ }
+ DRM_SYSCTL_PRINT("\n");
+ for (i = 0; i < dma->buf_count; i++) {
+ if (i && !(i%32)) DRM_SYSCTL_PRINT("\n");
+ DRM_SYSCTL_PRINT(" %d", dma->buflist[i]->list);
+ }
+ DRM_SYSCTL_PRINT("\n");
+
+ SYSCTL_OUT(req, "", 1);
+ return 0;
+}
+
+static int drm_bufs_info SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ int ret;
+
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc);
+ ret = _drm_bufs_info(oidp, arg1, arg2, req);
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+ return ret;
+}
+
+
+static int _drm_clients_info SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ drm_file_t *priv;
+ char buf[128];
+ int error;
+
+ DRM_SYSCTL_PRINT("a dev pid uid magic ioctls\n\n");
+ TAILQ_FOREACH(priv, &dev->files, link) {
+ DRM_SYSCTL_PRINT("%c %3d %5d %5d %10u %10lu\n",
+ priv->authenticated ? 'y' : 'n',
+ priv->minor,
+ priv->pid,
+ priv->uid,
+ priv->magic,
+ priv->ioctl_count);
+ }
+
+ SYSCTL_OUT(req, "", 1);
+ return 0;
+}
+
+static int drm_clients_info SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ int ret;
+
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc);
+ ret = _drm_clients_info(oidp, arg1, arg2, req);
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+ return ret;
+}
+
+#if DRM_DEBUG_CODExx
+
+static int _drm_vma_info SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ drm_vma_entry_t *pt;
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
+ unsigned long i;
+ struct vm_area_struct *vma;
+ unsigned long address;
+#if defined(__i386__)
+ unsigned int pgprot;
+#endif
+ char buf[128];
+ int error;
+
+ DRM_SYSCTL_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
+ atomic_read(&dev->vma_count),
+ high_memory, virt_to_phys(high_memory));
+ for (pt = dev->vmalist; pt; pt = pt->next) {
+ if (!(vma = pt->vma)) continue;
+ DRM_SYSCTL_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
+ pt->pid,
+ vma->vm_start,
+ vma->vm_end,
+ vma->vm_flags & VM_READ ? 'r' : '-',
+ vma->vm_flags & VM_WRITE ? 'w' : '-',
+ vma->vm_flags & VM_EXEC ? 'x' : '-',
+ vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
+ vma->vm_flags & VM_LOCKED ? 'l' : '-',
+ vma->vm_flags & VM_IO ? 'i' : '-',
+ vma->vm_offset );
+#if defined(__i386__)
+ pgprot = pgprot_val(vma->vm_page_prot);
+ DRM_SYSCTL_PRINT(" %c%c%c%c%c%c%c%c%c",
+ pgprot & _PAGE_PRESENT ? 'p' : '-',
+ pgprot & _PAGE_RW ? 'w' : 'r',
+ pgprot & _PAGE_USER ? 'u' : 's',
+ pgprot & _PAGE_PWT ? 't' : 'b',
+ pgprot & _PAGE_PCD ? 'u' : 'c',
+ pgprot & _PAGE_ACCESSED ? 'a' : '-',
+ pgprot & _PAGE_DIRTY ? 'd' : '-',
+ pgprot & _PAGE_4M ? 'm' : 'k',
+ pgprot & _PAGE_GLOBAL ? 'g' : 'l' );
+#endif
+ DRM_SYSCTL_PRINT("\n");
+ for (i = vma->vm_start; i < vma->vm_end; i += PAGE_SIZE) {
+ pgd = pgd_offset(vma->vm_mm, i);
+ pmd = pmd_offset(pgd, i);
+ pte = pte_offset(pmd, i);
+ if (pte_present(*pte)) {
+ address = __pa(pte_page(*pte))
+ + (i & (PAGE_SIZE-1));
+ DRM_SYSCTL_PRINT(" 0x%08lx -> 0x%08lx"
+ " %c%c%c%c%c\n",
+ i,
+ address,
+ pte_read(*pte) ? 'r' : '-',
+ pte_write(*pte) ? 'w' : '-',
+ pte_exec(*pte) ? 'x' : '-',
+ pte_dirty(*pte) ? 'd' : '-',
+ pte_young(*pte) ? 'a' : '-' );
+ } else {
+ DRM_SYSCTL_PRINT(" 0x%08lx\n", i);
+ }
+ }
+ }
+
+ SYSCTL_OUT(req, "", 1);
+ return 0;
+}
+
+static int drm_vma_info SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ int ret;
+
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc);
+ ret = _drm_vma_info(oidp, arg1, arg2, req);
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+ return ret;
+}
+#endif
+
+
+#if DRM_DMA_HISTOGRAM
+static int _drm_histo_info SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ drm_device_dma_t *dma = dev->dma;
+ int i;
+ unsigned long slot_value = DRM_DMA_HISTOGRAM_INITIAL;
+ unsigned long prev_value = 0;
+ drm_buf_t *buffer;
+ char buf[128];
+ int error;
+
+ DRM_SYSCTL_PRINT("general statistics:\n");
+ DRM_SYSCTL_PRINT("total %10u\n", atomic_read(&dev->histo.total));
+ DRM_SYSCTL_PRINT("open %10u\n", atomic_read(&dev->total_open));
+ DRM_SYSCTL_PRINT("close %10u\n", atomic_read(&dev->total_close));
+ DRM_SYSCTL_PRINT("ioctl %10u\n", atomic_read(&dev->total_ioctl));
+ DRM_SYSCTL_PRINT("irq %10u\n", atomic_read(&dev->total_irq));
+ DRM_SYSCTL_PRINT("ctx %10u\n", atomic_read(&dev->total_ctx));
+
+ DRM_SYSCTL_PRINT("\nlock statistics:\n");
+ DRM_SYSCTL_PRINT("locks %10u\n", atomic_read(&dev->total_locks));
+ DRM_SYSCTL_PRINT("unlocks %10u\n", atomic_read(&dev->total_unlocks));
+ DRM_SYSCTL_PRINT("contends %10u\n", atomic_read(&dev->total_contends));
+ DRM_SYSCTL_PRINT("sleeps %10u\n", atomic_read(&dev->total_sleeps));
+
+
+ if (dma) {
+ DRM_SYSCTL_PRINT("\ndma statistics:\n");
+ DRM_SYSCTL_PRINT("prio %10u\n",
+ atomic_read(&dma->total_prio));
+ DRM_SYSCTL_PRINT("bytes %10u\n",
+ atomic_read(&dma->total_bytes));
+ DRM_SYSCTL_PRINT("dmas %10u\n",
+ atomic_read(&dma->total_dmas));
+ DRM_SYSCTL_PRINT("missed:\n");
+ DRM_SYSCTL_PRINT(" dma %10u\n",
+ atomic_read(&dma->total_missed_dma));
+ DRM_SYSCTL_PRINT(" lock %10u\n",
+ atomic_read(&dma->total_missed_lock));
+ DRM_SYSCTL_PRINT(" free %10u\n",
+ atomic_read(&dma->total_missed_free));
+ DRM_SYSCTL_PRINT(" sched %10u\n",
+ atomic_read(&dma->total_missed_sched));
+ DRM_SYSCTL_PRINT("tried %10u\n",
+ atomic_read(&dma->total_tried));
+ DRM_SYSCTL_PRINT("hit %10u\n",
+ atomic_read(&dma->total_hit));
+ DRM_SYSCTL_PRINT("lost %10u\n",
+ atomic_read(&dma->total_lost));
+
+ buffer = dma->next_buffer;
+ if (buffer) {
+ DRM_SYSCTL_PRINT("next_buffer %7d\n", buffer->idx);
+ } else {
+ DRM_SYSCTL_PRINT("next_buffer none\n");
+ }
+ buffer = dma->this_buffer;
+ if (buffer) {
+ DRM_SYSCTL_PRINT("this_buffer %7d\n", buffer->idx);
+ } else {
+ DRM_SYSCTL_PRINT("this_buffer none\n");
+ }
+ }
+
+
+ DRM_SYSCTL_PRINT("\nvalues:\n");
+ if (dev->lock.hw_lock) {
+ DRM_SYSCTL_PRINT("lock 0x%08x\n",
+ dev->lock.hw_lock->lock);
+ } else {
+ DRM_SYSCTL_PRINT("lock none\n");
+ }
+ DRM_SYSCTL_PRINT("context_flag 0x%08x\n", dev->context_flag);
+ DRM_SYSCTL_PRINT("interrupt_flag 0x%08x\n", dev->interrupt_flag);
+ DRM_SYSCTL_PRINT("dma_flag 0x%08x\n", dev->dma_flag);
+
+ DRM_SYSCTL_PRINT("queue_count %10d\n", dev->queue_count);
+ DRM_SYSCTL_PRINT("last_context %10d\n", dev->last_context);
+ DRM_SYSCTL_PRINT("last_switch %10u\n", dev->last_switch);
+ DRM_SYSCTL_PRINT("last_checked %10d\n", dev->last_checked);
+
+
+ DRM_SYSCTL_PRINT("\n q2d d2c c2f"
+ " q2c q2f dma sch"
+ " ctx lacq lhld\n\n");
+ for (i = 0; i < DRM_DMA_HISTOGRAM_SLOTS; i++) {
+ DRM_SYSCTL_PRINT("%s %10lu %10u %10u %10u %10u %10u"
+ " %10u %10u %10u %10u %10u\n",
+ i == DRM_DMA_HISTOGRAM_SLOTS - 1 ? ">=" : "< ",
+ i == DRM_DMA_HISTOGRAM_SLOTS - 1
+ ? prev_value : slot_value ,
+
+ atomic_read(&dev->histo
+ .queued_to_dispatched[i]),
+ atomic_read(&dev->histo
+ .dispatched_to_completed[i]),
+ atomic_read(&dev->histo
+ .completed_to_freed[i]),
+
+ atomic_read(&dev->histo
+ .queued_to_completed[i]),
+ atomic_read(&dev->histo
+ .queued_to_freed[i]),
+ atomic_read(&dev->histo.dma[i]),
+ atomic_read(&dev->histo.schedule[i]),
+ atomic_read(&dev->histo.ctx[i]),
+ atomic_read(&dev->histo.lacq[i]),
+ atomic_read(&dev->histo.lhld[i]));
+ prev_value = slot_value;
+ slot_value = DRM_DMA_HISTOGRAM_NEXT(slot_value);
+ }
+ SYSCTL_OUT(req, "", 1);
+ return 0;
+}
+
+static int drm_histo_info SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ int ret;
+
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc);
+ ret = _drm_histo_info(oidp, arg1, arg2, req);
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+ return ret;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/vm.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/vm.c
new file mode 100644
index 000000000..9c457fca3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/vm.c
@@ -0,0 +1,104 @@
+/* vm.c -- Memory mapping for DRM -*- c -*-
+ * Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com
+ * Revised: Fri Aug 20 22:48:11 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c,v 1.7 1999/08/21 02:48:34 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c,v 1.1 1999/09/25 14:38:02 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+static int drm_dma_mmap(dev_t kdev, vm_offset_t offset, int prot)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_device_dma_t *dma = dev->dma;
+ unsigned long physical;
+ unsigned long page;
+
+ if (!dma) return -1; /* Error */
+ if (!dma->pagelist) return -1; /* Nothing allocated */
+
+ page = offset >> PAGE_SHIFT;
+ physical = dma->pagelist[page];
+
+ DRM_DEBUG("0x%08x (page %lu) => 0x%08lx\n", offset, page, physical);
+ return atop(physical);
+}
+
+int drm_mmap(dev_t kdev, vm_offset_t offset, int prot)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_map_t *map = NULL;
+ int i;
+
+ /* DRM_DEBUG("offset = 0x%x\n", offset); */
+
+ if (dev->dma
+ && offset >= 0
+ && offset < ptoa(dev->dma->page_count))
+ return drm_dma_mmap(kdev, offset, prot);
+
+ /* A sequential search of a linked list is
+ fine here because: 1) there will only be
+ about 5-10 entries in the list and, 2) a
+ DRI client only has to do this mapping
+ once, so it doesn't have to be optimized
+ for performance, even if the list was a
+ bit longer. */
+ for (i = 0; i < dev->map_count; i++) {
+ map = dev->maplist[i];
+ /* DRM_DEBUG("considering 0x%x..0x%x\n", map->offset, map->offset + map->size - 1); */
+ if (offset >= map->offset
+ && offset < map->offset + map->size) break;
+ }
+
+ if (i >= dev->map_count) {
+ DRM_DEBUG("can't find map\n");
+ return -1;
+ }
+ if (!map || ((map->flags&_DRM_RESTRICTED) && suser(curproc))) {
+ DRM_DEBUG("restricted map\n");
+ return -1;
+ }
+
+ switch (map->type) {
+ case _DRM_FRAME_BUFFER:
+ case _DRM_REGISTERS:
+ case _DRM_AGP:
+ return atop(offset);
+ case _DRM_SHM:
+ return atop(vtophys(offset));
+ default:
+ return -1; /* This should never happen. */
+ }
+ DRM_DEBUG("bailing out\n");
+
+ return -1;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h
new file mode 100644
index 000000000..863836a66
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h
@@ -0,0 +1,708 @@
+/* drmP.h -- Private header for Direct Rendering Manager -*- c -*-
+ * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
+ * Revised: Tue Oct 12 08:51:07 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h,v 1.58 1999/08/30 13:05:00 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h,v 1.1 1999/09/25 14:37:59 dawes Exp $
+ *
+ */
+
+#ifndef _DRM_P_H_
+#define _DRM_P_H_
+
+#ifdef _KERNEL
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/stat.h>
+#include <sys/proc.h>
+#include <sys/lock.h>
+#include <sys/fcntl.h>
+#include <sys/uio.h>
+#include <sys/filio.h>
+#include <sys/sysctl.h>
+#include <sys/select.h>
+#include <sys/bus.h>
+#include <sys/taskqueue.h>
+
+#ifdef DRM_AGP
+#include <pci/agpvar.h>
+#endif
+
+#include "drm.h"
+
+typedef u_int32_t atomic_t;
+typedef u_int32_t cycles_t;
+typedef u_int32_t spinlock_t;
+#define atomic_set(p, v) (*(p) = (v))
+#define atomic_read(p) (*(p))
+#define atomic_inc(p) atomic_add_int(p, 1)
+#define atomic_dec(p) atomic_subtract_int(p, 1)
+#define atomic_add(n, p) atomic_add_int(p, n)
+#define atomic_sub(n, p) atomic_subtract_int(p, n)
+
+/* Fake this */
+static __inline u_int32_t
+test_and_set_bit(int b, volatile u_int32_t *p)
+{
+ u_int32_t m = 1<<b;
+ u_int32_t r = *p & m;
+ *p |= m;
+ return r;
+}
+
+static __inline void
+clear_bit(int b, volatile u_int32_t *p)
+{
+ atomic_clear_int(p + (b >> 5), 1 << (b & 0x1f));
+}
+
+static __inline void
+set_bit(int b, volatile u_int32_t *p)
+{
+ atomic_set_int(p + (b >> 5), 1 << (b & 0x1f));
+}
+
+static __inline int
+test_bit(int b, volatile u_int32_t *p)
+{
+ return p[b >> 5] & (1 << (b & 0x1f));
+}
+
+static __inline int
+find_first_zero_bit(volatile u_int32_t *p, int max)
+{
+ int b;
+
+ for (b = 0; b < max; b += 32) {
+ if (p[b >> 5]) {
+ for (;;) {
+ if (p[b >> 5] & (1 << (b & 0x1f)))
+ return b;
+ b++;
+ }
+ }
+ }
+ return max;
+}
+
+#define spldrm() spltty()
+
+#define memset(p, v, s) bzero(p, s)
+
+/*
+ * Software interrupts for DMA pipe feeding. The FreeBSD kernel apis
+ * are severely lacking here.
+ */
+#define SWI_DRI (SWI_VM+2)
+
+#define DRM_DEBUG_CODE 2 /* Include debugging code (if > 1, then
+ also include looping detection. */
+#define DRM_DMA_HISTOGRAM 1 /* Make histogram of DMA latency. */
+
+#define DRM_HASH_SIZE 16 /* Size of key hash table */
+#define DRM_KERNEL_CONTEXT 0 /* Change drm_resctx if changed */
+#define DRM_RESERVED_CONTEXTS 1 /* Change drm_resctx if changed */
+#define DRM_LOOPING_LIMIT 5000000
+#define DRM_BSZ 1024 /* Buffer size for /dev/drm? output */
+#define DRM_TIME_SLICE (hz/20) /* Time slice for GLXContexts */
+#define DRM_LOCK_SLICE 1 /* Time slice for lock, in jiffies */
+
+#define DRM_FLAG_DEBUG 0x01
+#define DRM_FLAG_NOCTX 0x02
+
+#define DRM_MEM_DMA 0
+#define DRM_MEM_SAREA 1
+#define DRM_MEM_DRIVER 2
+#define DRM_MEM_MAGIC 3
+#define DRM_MEM_IOCTLS 4
+#define DRM_MEM_MAPS 5
+#define DRM_MEM_VMAS 6
+#define DRM_MEM_BUFS 7
+#define DRM_MEM_SEGS 8
+#define DRM_MEM_PAGES 9
+#define DRM_MEM_FILES 10
+#define DRM_MEM_QUEUES 11
+#define DRM_MEM_CMDS 12
+#define DRM_MEM_MAPPINGS 13
+#define DRM_MEM_BUFLISTS 14
+#define DRM_MEM_AGPLISTS 15
+#define DRM_MEM_TOTALAGP 16
+#define DRM_MEM_BOUNDAGP 17
+#define DRM_MEM_CTXBITMAP 18
+
+#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
+
+ /* Backward compatibility section */
+#ifndef _PAGE_PWT
+ /* The name of _PAGE_WT was changed to
+ _PAGE_PWT in Linux 2.2.6 */
+#define _PAGE_PWT _PAGE_WT
+#endif
+
+#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)
+#define _DRM_CAS(lock,old,new,__ret) \
+ do { \
+ int __dummy; /* Can't mark eax as clobbered */ \
+ __asm__ __volatile__( \
+ "lock ; cmpxchg %4,%1\n\t" \
+ "setnz %0" \
+ : "=d" (__ret), \
+ "=m" (__drm_dummy_lock(lock)), \
+ "=a" (__dummy) \
+ : "2" (old), \
+ "r" (new)); \
+ } while (0)
+
+
+
+ /* Macros to make printk easier */
+#define DRM_ERROR(fmt, arg...) \
+ printf("error: " "[" DRM_NAME ":" __FUNCTION__ "] *ERROR* " fmt , ##arg)
+#define DRM_MEM_ERROR(area, fmt, arg...) \
+ printf("error: " "[" DRM_NAME ":" __FUNCTION__ ":%s] *ERROR* " fmt , \
+ drm_mem_stats[area].name , ##arg)
+#define DRM_INFO(fmt, arg...) printf("info: " "[" DRM_NAME "] " fmt , ##arg)
+
+#if DRM_DEBUG_CODE
+#define DRM_DEBUG(fmt, arg...) \
+ do { \
+ if (drm_flags&DRM_FLAG_DEBUG) \
+ printf("[" DRM_NAME ":" __FUNCTION__ "] " fmt , \
+ ##arg); \
+ } while (0)
+#else
+#define DRM_DEBUG(fmt, arg...) do { } while (0)
+#endif
+
+#define DRM_PROC_LIMIT (PAGE_SIZE-80)
+
+#define DRM_SYSCTL_PRINT(fmt, arg...) \
+ snprintf(buf, sizeof(buf), fmt, ##arg); \
+ error = SYSCTL_OUT(req, buf, strlen(buf)); \
+ if (error) return error;
+
+#define DRM_SYSCTL_PRINT_RET(ret, fmt, arg...) \
+ snprintf(buf, sizeof(buf), fmt, ##arg); \
+ error = SYSCTL_OUT(req, buf, strlen(buf)); \
+ if (error) { ret; return error; }
+
+ /* Internal types and structures */
+#define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+#define DRM_MIN(a,b) ((a)<(b)?(a):(b))
+#define DRM_MAX(a,b) ((a)>(b)?(a):(b))
+
+#define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1))
+#define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
+#define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist)
+
+typedef struct drm_ioctl_desc {
+ d_ioctl_t *func;
+ int auth_needed;
+ int root_only;
+} drm_ioctl_desc_t;
+
+typedef struct drm_devstate {
+ pid_t owner; /* X server pid holding x_lock */
+
+} drm_devstate_t;
+
+typedef struct drm_magic_entry {
+ drm_magic_t magic;
+ struct drm_file *priv;
+ struct drm_magic_entry *next;
+} drm_magic_entry_t;
+
+typedef struct drm_magic_head {
+ struct drm_magic_entry *head;
+ struct drm_magic_entry *tail;
+} drm_magic_head_t;
+
+typedef struct drm_vma_entry {
+ struct vm_area_struct *vma;
+ struct drm_vma_entry *next;
+ pid_t pid;
+} drm_vma_entry_t;
+
+typedef struct drm_buf {
+ int idx; /* Index into master buflist */
+ int total; /* Buffer size */
+ int order; /* log-base-2(total) */
+ int used; /* Amount of buffer in use (for DMA) */
+ unsigned long offset; /* Byte offset (used internally) */
+ void *address; /* Address of buffer */
+ unsigned long bus_address; /* Bus address of buffer */
+ struct drm_buf *next; /* Kernel-only: used for free list */
+ __volatile__ int waiting; /* On kernel DMA queue */
+ __volatile__ int pending; /* On hardware DMA queue */
+ int dma_wait; /* Processes waiting */
+ pid_t pid; /* PID of holding process */
+ int context; /* Kernel queue for this buffer */
+ int while_locked;/* Dispatch this buffer while locked */
+ enum {
+ DRM_LIST_NONE = 0,
+ DRM_LIST_FREE = 1,
+ DRM_LIST_WAIT = 2,
+ DRM_LIST_PEND = 3,
+ DRM_LIST_PRIO = 4,
+ DRM_LIST_RECLAIM = 5
+ } list; /* Which list we're on */
+
+ void *dev_private;
+ int dev_priv_size;
+
+#if DRM_DMA_HISTOGRAM
+ struct timespec time_queued; /* Queued to kernel DMA queue */
+ struct timespec time_dispatched; /* Dispatched to hardware */
+ struct timespec time_completed; /* Completed by hardware */
+ struct timespec time_freed; /* Back on freelist */
+#endif
+} drm_buf_t;
+
+#if DRM_DMA_HISTOGRAM
+#define DRM_DMA_HISTOGRAM_SLOTS 9
+#define DRM_DMA_HISTOGRAM_INITIAL 10
+#define DRM_DMA_HISTOGRAM_NEXT(current) ((current)*10)
+typedef struct drm_histogram {
+ atomic_t total;
+
+ atomic_t queued_to_dispatched[DRM_DMA_HISTOGRAM_SLOTS];
+ atomic_t dispatched_to_completed[DRM_DMA_HISTOGRAM_SLOTS];
+ atomic_t completed_to_freed[DRM_DMA_HISTOGRAM_SLOTS];
+
+ atomic_t queued_to_completed[DRM_DMA_HISTOGRAM_SLOTS];
+ atomic_t queued_to_freed[DRM_DMA_HISTOGRAM_SLOTS];
+
+ atomic_t dma[DRM_DMA_HISTOGRAM_SLOTS];
+ atomic_t schedule[DRM_DMA_HISTOGRAM_SLOTS];
+ atomic_t ctx[DRM_DMA_HISTOGRAM_SLOTS];
+ atomic_t lacq[DRM_DMA_HISTOGRAM_SLOTS];
+ atomic_t lhld[DRM_DMA_HISTOGRAM_SLOTS];
+} drm_histogram_t;
+#endif
+
+ /* bufs is one longer than it has to be */
+typedef struct drm_waitlist {
+ int count; /* Number of possible buffers */
+ drm_buf_t **bufs; /* List of pointers to buffers */
+ drm_buf_t **rp; /* Read pointer */
+ drm_buf_t **wp; /* Write pointer */
+ drm_buf_t **end; /* End pointer */
+ spinlock_t read_lock;
+ spinlock_t write_lock;
+} drm_waitlist_t;
+
+typedef struct drm_freelist {
+ int initialized; /* Freelist in use */
+ atomic_t count; /* Number of free buffers */
+ drm_buf_t *next; /* End pointer */
+
+ int waiting; /* Processes waiting on free bufs */
+ int low_mark; /* Low water mark */
+ int high_mark; /* High water mark */
+ atomic_t wfh; /* If waiting for high mark */
+} drm_freelist_t;
+
+typedef struct drm_buf_entry {
+ int buf_size;
+ int buf_count;
+ drm_buf_t *buflist;
+ int seg_count;
+ int page_order;
+ unsigned long *seglist;
+
+ drm_freelist_t freelist;
+} drm_buf_entry_t;
+
+typedef struct drm_hw_lock {
+ __volatile__ unsigned int lock;
+ char padding[60]; /* Pad to cache line */
+} drm_hw_lock_t;
+
+typedef TAILQ_HEAD(drm_file_list, drm_file) drm_file_list_t;
+typedef struct drm_file {
+ TAILQ_ENTRY(drm_file) link;
+ int authenticated;
+ int minor;
+ pid_t pid;
+ uid_t uid;
+ int refs;
+ drm_magic_t magic;
+ unsigned long ioctl_count;
+ struct drm_device *devXX;
+} drm_file_t;
+
+
+typedef struct drm_queue {
+ atomic_t use_count; /* Outstanding uses (+1) */
+ atomic_t finalization; /* Finalization in progress */
+ atomic_t block_count; /* Count of processes waiting */
+ atomic_t block_read; /* Queue blocked for reads */
+ int read_queue; /* Processes waiting on block_read */
+ atomic_t block_write; /* Queue blocked for writes */
+ int write_queue; /* Processes waiting on block_write */
+ atomic_t total_queued; /* Total queued statistic */
+ atomic_t total_flushed;/* Total flushes statistic */
+ atomic_t total_locks; /* Total locks statistics */
+ drm_ctx_flags_t flags; /* Context preserving and 2D-only */
+ drm_waitlist_t waitlist; /* Pending buffers */
+ int flush_queue; /* Processes waiting until flush */
+} drm_queue_t;
+
+typedef struct drm_lock_data {
+ drm_hw_lock_t *hw_lock; /* Hardware lock */
+ pid_t pid; /* PID of lock holder (0=kernel) */
+ int lock_queue; /* Queue of blocked processes */
+ unsigned long lock_time; /* Time of last lock in jiffies */
+} drm_lock_data_t;
+
+typedef struct drm_device_dma {
+ /* Performance Counters */
+ atomic_t total_prio; /* Total DRM_DMA_PRIORITY */
+ atomic_t total_bytes; /* Total bytes DMA'd */
+ atomic_t total_dmas; /* Total DMA buffers dispatched */
+
+ atomic_t total_missed_dma; /* Missed drm_do_dma */
+ atomic_t total_missed_lock; /* Missed lock in drm_do_dma */
+ atomic_t total_missed_free; /* Missed drm_free_this_buffer */
+ atomic_t total_missed_sched;/* Missed drm_dma_schedule */
+
+ atomic_t total_tried; /* Tried next_buffer */
+ atomic_t total_hit; /* Sent next_buffer */
+ atomic_t total_lost; /* Lost interrupt */
+
+ drm_buf_entry_t bufs[DRM_MAX_ORDER+1];
+ int buf_count;
+ drm_buf_t **buflist; /* Vector of pointers info bufs */
+ int seg_count;
+ int page_count;
+ vm_offset_t *pagelist;
+ unsigned long byte_count;
+ enum {
+ _DRM_DMA_USE_AGP = 0x01
+ } flags;
+
+ /* DMA support */
+ drm_buf_t *this_buffer; /* Buffer being sent */
+ drm_buf_t *next_buffer; /* Selected buffer to send */
+ drm_queue_t *next_queue; /* Queue from which buffer selected*/
+ int waiting; /* Processes waiting on free bufs */
+} drm_device_dma_t;
+
+#ifdef DRM_AGP
+
+typedef struct drm_agp_mem {
+ void *handle;
+ unsigned long bound; /* address */
+ int pages;
+ struct drm_agp_mem *prev;
+ struct drm_agp_mem *next;
+} drm_agp_mem_t;
+
+typedef struct drm_agp_head {
+ device_t agpdev;
+ struct agp_info info;
+ const char *chipset;
+ drm_agp_mem_t *memory;
+ unsigned long mode;
+ int enabled;
+ int acquired;
+ unsigned long base;
+ int agp_mtrr;
+} drm_agp_head_t;
+
+#endif
+
+typedef struct drm_device {
+ const char *name; /* Simple driver name */
+ char *unique; /* Unique identifier: e.g., busid */
+ int unique_len; /* Length of unique field */
+ device_t device; /* Device instance from newbus */
+ dev_t devnode; /* Device number for mknod */
+ char *devname; /* For /proc/interrupts */
+
+ int blocked; /* Blocked due to VC switch? */
+ int flags; /* Flags to open(2) */
+ int writable; /* Opened with FWRITE */
+ struct proc_dir_entry *root; /* Root for this device's entries */
+
+ /* Locks */
+ struct simplelock count_lock; /* For inuse, open_count, buf_use */
+ struct lock dev_lock; /* For others */
+
+ /* Usage Counters */
+ int open_count; /* Outstanding files open */
+ atomic_t ioctl_count; /* Outstanding IOCTLs pending */
+ atomic_t vma_count; /* Outstanding vma areas open */
+ int buf_use; /* Buffers in use -- cannot alloc */
+ atomic_t buf_alloc; /* Buffer allocation in progress */
+
+ /* Performance Counters */
+ atomic_t total_open;
+ atomic_t total_close;
+ atomic_t total_ioctl;
+ atomic_t total_irq; /* Total interruptions */
+ atomic_t total_ctx; /* Total context switches */
+
+ atomic_t total_locks;
+ atomic_t total_unlocks;
+ atomic_t total_contends;
+ atomic_t total_sleeps;
+
+ /* Authentication */
+ drm_file_list_t files;
+ drm_magic_head_t magiclist[DRM_HASH_SIZE];
+
+ /* Memory management */
+ drm_map_t **maplist; /* Vector of pointers to regions */
+ int map_count; /* Number of mappable regions */
+
+ drm_vma_entry_t *vmalist; /* List of vmas (for debugging) */
+ drm_lock_data_t lock; /* Information on hardware lock */
+
+ /* DMA queues (contexts) */
+ int queue_count; /* Number of active DMA queues */
+ int queue_reserved; /* Number of reserved DMA queues */
+ int queue_slots; /* Actual length of queuelist */
+ drm_queue_t **queuelist; /* Vector of pointers to DMA queues */
+ drm_device_dma_t *dma; /* Optional pointer for DMA support */
+
+ /* Context support */
+ struct resource *irq; /* Interrupt used by board */
+ void *irqh; /* Handle from bus_setup_intr */
+ __volatile__ int context_flag; /* Context swapping flag */
+ __volatile__ int interrupt_flag;/* Interruption handler flag */
+ __volatile__ int dma_flag; /* DMA dispatch flag */
+ struct callout timer; /* Timer for delaying ctx switch */
+ int context_wait; /* Processes waiting on ctx switch */
+ int last_checked; /* Last context checked for DMA */
+ int last_context; /* Last current context */
+ int last_switch; /* Time at last context switch */
+ struct task task;
+ struct timespec ctx_start;
+ struct timespec lck_start;
+#if DRM_DMA_HISTOGRAM
+ drm_histogram_t histo;
+#endif
+
+ /* Callback to X server for context switch
+ and for heavy-handed reset. */
+ char buf[DRM_BSZ]; /* Output buffer */
+ char *buf_rp; /* Read pointer */
+ char *buf_wp; /* Write pointer */
+ char *buf_end; /* End pointer */
+ struct sigio *buf_sigio; /* Processes waiting for SIGIO */
+ struct selinfo buf_sel; /* Workspace for select/poll */
+ int buf_readers; /* Processes waiting to read */
+ int buf_writers; /* Processes waiting to ctx switch */
+ int buf_selecting; /* True if poll sleeper */
+
+ /* Sysctl support */
+ struct drm_sysctl_info *sysctl;
+
+#ifdef DRM_AGP
+ drm_agp_head_t *agp;
+#endif
+ u_int32_t *ctx_bitmap;
+ void *dev_private;
+} drm_device_t;
+
+
+ /* Internal function definitions */
+
+ /* Misc. support (init.c) */
+extern int drm_flags;
+extern void drm_parse_options(char *s);
+
+
+ /* Device support (fops.c) */
+extern drm_file_t *drm_find_file_by_proc(drm_device_t *dev, struct proc *p);
+extern int drm_open_helper(dev_t kdev, int flags, int fmt, struct proc *p,
+ drm_device_t *dev);
+extern d_close_t drm_close;
+extern d_read_t drm_read;
+extern d_write_t drm_write;
+extern d_poll_t drm_poll;
+extern int drm_fsetown(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p);
+extern int drm_fgetown(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p);
+extern int drm_write_string(drm_device_t *dev, const char *s);
+
+#if 0
+ /* Mapping support (vm.c) */
+extern unsigned long drm_vm_nopage(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access);
+extern unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access);
+extern unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access);
+extern void drm_vm_open(struct vm_area_struct *vma);
+extern void drm_vm_close(struct vm_area_struct *vma);
+extern int drm_mmap_dma(struct file *filp,
+ struct vm_area_struct *vma);
+#endif
+extern d_mmap_t drm_mmap;
+
+ /* Proc support (proc.c) */
+extern int drm_sysctl_init(drm_device_t *dev);
+extern int drm_sysctl_cleanup(drm_device_t *dev);
+
+ /* Memory management support (memory.c) */
+extern void drm_mem_init(void);
+extern int drm_mem_info SYSCTL_HANDLER_ARGS;
+extern void *drm_alloc(size_t size, int area);
+extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size,
+ int area);
+extern char *drm_strdup(const char *s, int area);
+extern void drm_strfree(char *s, int area);
+extern void drm_free(void *pt, size_t size, int area);
+extern unsigned long drm_alloc_pages(int order, int area);
+extern void drm_free_pages(unsigned long address, int order,
+ int area);
+extern void *drm_ioremap(unsigned long offset, unsigned long size);
+extern void drm_ioremapfree(void *pt, unsigned long size);
+
+#ifdef DRM_AGP
+extern void *drm_alloc_agp(int pages, u_int32_t type);
+extern int drm_free_agp(void *handle, int pages);
+extern int drm_bind_agp(void *handle, unsigned int start);
+extern int drm_unbind_agp(void *handle);
+#endif
+
+ /* Buffer management support (bufs.c) */
+extern int drm_order(unsigned long size);
+extern d_ioctl_t drm_addmap;
+extern d_ioctl_t drm_addbufs;
+extern d_ioctl_t drm_infobufs;
+extern d_ioctl_t drm_markbufs;
+extern d_ioctl_t drm_freebufs;
+extern d_ioctl_t drm_mapbufs;
+
+
+ /* Buffer list management support (lists.c) */
+extern int drm_waitlist_create(drm_waitlist_t *bl, int count);
+extern int drm_waitlist_destroy(drm_waitlist_t *bl);
+extern int drm_waitlist_put(drm_waitlist_t *bl, drm_buf_t *buf);
+extern drm_buf_t *drm_waitlist_get(drm_waitlist_t *bl);
+
+extern int drm_freelist_create(drm_freelist_t *bl, int count);
+extern int drm_freelist_destroy(drm_freelist_t *bl);
+extern int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl,
+ drm_buf_t *buf);
+extern drm_buf_t *drm_freelist_get(drm_freelist_t *bl, int block);
+
+ /* DMA support (gen_dma.c) */
+extern void drm_dma_setup(drm_device_t *dev);
+extern void drm_dma_takedown(drm_device_t *dev);
+extern void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf);
+extern void drm_reclaim_buffers(drm_device_t *dev, pid_t pid);
+extern int drm_context_switch(drm_device_t *dev, int old, int new);
+extern int drm_context_switch_complete(drm_device_t *dev, int new);
+extern void drm_wakeup(drm_device_t *dev, drm_buf_t *buf);
+extern void drm_clear_next_buffer(drm_device_t *dev);
+extern int drm_select_queue(drm_device_t *dev,
+ void (*wrapper)(void *));
+extern int drm_dma_enqueue(drm_device_t *dev, drm_dma_t *dma);
+extern int drm_dma_get_buffers(drm_device_t *dev, drm_dma_t *dma);
+#if DRM_DMA_HISTOGRAM
+extern int drm_histogram_slot(struct timespec *ts);
+extern void drm_histogram_compute(drm_device_t *dev, drm_buf_t *buf);
+#endif
+
+
+ /* Misc. IOCTL support (ioctl.c) */
+extern d_ioctl_t drm_irq_busid;
+extern d_ioctl_t drm_getunique;
+extern d_ioctl_t drm_setunique;
+
+
+ /* Context IOCTL support (context.c) */
+extern d_ioctl_t drm_resctx;
+extern d_ioctl_t drm_addctx;
+extern d_ioctl_t drm_modctx;
+extern d_ioctl_t drm_getctx;
+extern d_ioctl_t drm_switchctx;
+extern d_ioctl_t drm_newctx;
+extern d_ioctl_t drm_rmctx;
+
+
+ /* Drawable IOCTL support (drawable.c) */
+extern d_ioctl_t drm_adddraw;
+extern d_ioctl_t drm_rmdraw;
+
+
+ /* Authentication IOCTL support (auth.c) */
+extern int drm_add_magic(drm_device_t *dev, drm_file_t *priv,
+ drm_magic_t magic);
+extern int drm_remove_magic(drm_device_t *dev, drm_magic_t magic);
+extern d_ioctl_t drm_getmagic;
+extern d_ioctl_t drm_authmagic;
+
+
+ /* Locking IOCTL support (lock.c) */
+extern d_ioctl_t drm_block;
+extern d_ioctl_t drm_unblock;
+extern int drm_lock_take(__volatile__ unsigned int *lock,
+ unsigned int context);
+extern int drm_lock_transfer(drm_device_t *dev,
+ __volatile__ unsigned int *lock,
+ unsigned int context);
+extern int drm_lock_free(drm_device_t *dev,
+ __volatile__ unsigned int *lock,
+ unsigned int context);
+extern d_ioctl_t drm_finish;
+extern int drm_flush_unblock(drm_device_t *dev, int context,
+ drm_lock_flags_t flags);
+extern int drm_flush_block_and_flush(drm_device_t *dev, int context,
+ drm_lock_flags_t flags);
+
+ /* Context Bitmap support (ctxbitmap.c) */
+extern int drm_ctxbitmap_init(drm_device_t *dev);
+extern void drm_ctxbitmap_cleanup(drm_device_t *dev);
+extern int drm_ctxbitmap_next(drm_device_t *dev);
+extern void drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle);
+
+#ifdef DRM_AGP
+ /* AGP/GART support (agpsupport.c) */
+extern drm_agp_head_t *drm_agp_init(void);
+extern d_ioctl_t drm_agp_acquire;
+extern d_ioctl_t drm_agp_release;
+extern d_ioctl_t drm_agp_enable;
+extern d_ioctl_t drm_agp_info;
+extern d_ioctl_t drm_agp_alloc;
+extern d_ioctl_t drm_agp_free;
+extern d_ioctl_t drm_agp_unbind;
+extern d_ioctl_t drm_agp_bind;
+#endif
+#endif
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma/Makefile b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma/Makefile
new file mode 100644
index 000000000..dd6110382
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma/Makefile
@@ -0,0 +1,15 @@
+# $FreeBSD$
+
+KMOD = gamma
+SRCS = gamma_drv.c gamma_dma.c
+SRCS += device_if.h bus_if.h pci_if.h
+CFLAGS += ${DEBUG_FLAGS} -I..
+KERN = /usr/src/sys
+
+@:
+ ln -sf /sys @
+
+machine:
+ ln -sf /sys/i386/include machine
+
+.include "/usr/src/sys/conf/kmod.mk"
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma/gamma_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma/gamma_dma.c
new file mode 100644
index 000000000..177440db8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma/gamma_dma.c
@@ -0,0 +1,802 @@
+/* gamma_dma.c -- DMA support for GMX 2000 -*- c -*-
+ * Created: Fri Mar 19 14:30:16 1999 by faith@precisioninsight.com
+ * Revised: Thu Sep 16 12:55:37 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c,v 1.9 1999/09/16 16:56:18 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c,v 1.1 1999/09/25 14:38:00 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+#include "gamma_drv.h"
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+/* WARNING!!! MAGIC NUMBER!!! The number of regions already added to the
+ kernel must be specified here. Currently, the number is 2. This must
+ match the order the X server uses for instantiating register regions ,
+ or must be passed in a new ioctl. */
+#define GAMMA_REG(reg) \
+ (2 \
+ + ((reg < 0x1000) \
+ ? 0 \
+ : ((reg < 0x10000) ? 1 : ((reg < 0x11000) ? 2 : 3))))
+
+#define GAMMA_OFF(reg) \
+ ((reg < 0x1000) \
+ ? reg \
+ : ((reg < 0x10000) \
+ ? (reg - 0x1000) \
+ : ((reg < 0x11000) \
+ ? (reg - 0x10000) \
+ : (reg - 0x11000))))
+
+#define GAMMA_BASE(reg) ((unsigned long)dev->maplist[GAMMA_REG(reg)]->handle)
+#define GAMMA_ADDR(reg) (GAMMA_BASE(reg) + GAMMA_OFF(reg))
+#define GAMMA_DEREF(reg) *(__volatile__ int *)GAMMA_ADDR(reg)
+#define GAMMA_READ(reg) GAMMA_DEREF(reg)
+#define GAMMA_WRITE(reg,val) do { GAMMA_DEREF(reg) = val; } while (0)
+
+#define GAMMA_BROADCASTMASK 0x9378
+#define GAMMA_COMMANDINTENABLE 0x0c48
+#define GAMMA_DMAADDRESS 0x0028
+#define GAMMA_DMACOUNT 0x0030
+#define GAMMA_FILTERMODE 0x8c00
+#define GAMMA_GCOMMANDINTFLAGS 0x0c50
+#define GAMMA_GCOMMANDMODE 0x0c40
+#define GAMMA_GCOMMANDSTATUS 0x0c60
+#define GAMMA_GDELAYTIMER 0x0c38
+#define GAMMA_GDMACONTROL 0x0060
+#define GAMMA_GINTENABLE 0x0808
+#define GAMMA_GINTFLAGS 0x0810
+#define GAMMA_INFIFOSPACE 0x0018
+#define GAMMA_OUTFIFOWORDS 0x0020
+#define GAMMA_OUTPUTFIFO 0x2000
+#define GAMMA_SYNC 0x8c40
+#define GAMMA_SYNC_TAG 0x0188
+
+static __inline void gamma_dma_dispatch(drm_device_t *dev,
+ vm_offset_t address,
+ vm_size_t length)
+{
+ GAMMA_WRITE(GAMMA_DMAADDRESS, vtophys(address));
+ while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4)
+ ;
+ GAMMA_WRITE(GAMMA_DMACOUNT, length / 4);
+}
+
+static __inline void gamma_dma_quiescent(drm_device_t *dev)
+{
+ while (GAMMA_READ(GAMMA_DMACOUNT))
+ ;
+ while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
+ ;
+ GAMMA_WRITE(GAMMA_BROADCASTMASK, 3);
+ GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10);
+ GAMMA_WRITE(GAMMA_SYNC, 0);
+
+ /* Read from first MX */
+ do {
+ while (!GAMMA_READ(GAMMA_OUTFIFOWORDS))
+ ;
+ } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG);
+
+
+ /* Read from second MX */
+ do {
+ while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000))
+ ;
+ } while (GAMMA_READ(GAMMA_OUTPUTFIFO + 0x10000) != GAMMA_SYNC_TAG);
+}
+
+static __inline void gamma_dma_ready(drm_device_t *dev)
+{
+ while (GAMMA_READ(GAMMA_DMACOUNT))
+ ;
+}
+
+static __inline int gamma_dma_is_ready(drm_device_t *dev)
+{
+ return !GAMMA_READ(GAMMA_DMACOUNT);
+}
+
+static void gamma_dma_service(void *arg)
+{
+ drm_device_t *dev = (drm_device_t *)arg;
+ drm_device_dma_t *dma = dev->dma;
+
+ atomic_inc(&dev->total_irq);
+ GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */
+ GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8);
+ GAMMA_WRITE(GAMMA_GINTFLAGS, 0x2001);
+ if (gamma_dma_is_ready(dev)) {
+ /* Free previous buffer */
+ if (test_and_set_bit(0, &dev->dma_flag)) {
+ atomic_inc(&dma->total_missed_free);
+ return;
+ }
+ if (dma->this_buffer) {
+ drm_free_buffer(dev, dma->this_buffer);
+ dma->this_buffer = NULL;
+ }
+ clear_bit(0, &dev->dma_flag);
+
+#if 0
+ /* Dispatch new buffer */
+ queue_task(&dev->tq, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+#endif
+ }
+}
+
+/* Only called by gamma_dma_schedule. */
+static int gamma_do_dma(drm_device_t *dev, int locked)
+{
+ unsigned long address;
+ unsigned long length;
+ drm_buf_t *buf;
+ int retcode = 0;
+ drm_device_dma_t *dma = dev->dma;
+#if DRM_DMA_HISTOGRAM
+ struct timespec dma_start, dma_stop;
+#endif
+
+ if (test_and_set_bit(0, &dev->dma_flag)) {
+ atomic_inc(&dma->total_missed_dma);
+ return EBUSY;
+ }
+
+#if DRM_DMA_HISTOGRAM
+ getnanotime(&dma_start);
+#endif
+
+ if (!dma->next_buffer) {
+ DRM_ERROR("No next_buffer\n");
+ clear_bit(0, &dev->dma_flag);
+ return EINVAL;
+ }
+
+ buf = dma->next_buffer;
+ address = (unsigned long)buf->address;
+ length = buf->used;
+
+ DRM_DEBUG("context %d, buffer %d (%ld bytes)\n",
+ buf->context, buf->idx, length);
+
+ if (buf->list == DRM_LIST_RECLAIM) {
+ drm_clear_next_buffer(dev);
+ drm_free_buffer(dev, buf);
+ clear_bit(0, &dev->dma_flag);
+ return EINVAL;
+ }
+
+ if (!length) {
+ DRM_ERROR("0 length buffer\n");
+ drm_clear_next_buffer(dev);
+ drm_free_buffer(dev, buf);
+ clear_bit(0, &dev->dma_flag);
+ return 0;
+ }
+
+ if (!gamma_dma_is_ready(dev)) {
+ clear_bit(0, &dev->dma_flag);
+ return EBUSY;
+ }
+
+ if (buf->while_locked) {
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("Dispatching buffer %d from pid %d"
+ " \"while locked\", but no lock held\n",
+ buf->idx, buf->pid);
+ }
+ } else {
+ if (!locked && !drm_lock_take(&dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ atomic_inc(&dma->total_missed_lock);
+ clear_bit(0, &dev->dma_flag);
+ return EBUSY;
+ }
+ }
+
+ if (dev->last_context != buf->context
+ && !(dev->queuelist[buf->context]->flags
+ & _DRM_CONTEXT_PRESERVED)) {
+ /* PRE: dev->last_context != buf->context */
+ if (drm_context_switch(dev, dev->last_context, buf->context)) {
+ drm_clear_next_buffer(dev);
+ drm_free_buffer(dev, buf);
+ }
+ retcode = EBUSY;
+ goto cleanup;
+
+ /* POST: we will wait for the context
+ switch and will dispatch on a later call
+ when dev->last_context == buf->context.
+ NOTE WE HOLD THE LOCK THROUGHOUT THIS
+ TIME! */
+ }
+
+ drm_clear_next_buffer(dev);
+ buf->pending = 1;
+ buf->waiting = 0;
+ buf->list = DRM_LIST_PEND;
+#if DRM_DMA_HISTOGRAM
+ getnanotime(&buf->time_dispatched);
+#endif
+
+ gamma_dma_dispatch(dev, address, length);
+ drm_free_buffer(dev, dma->this_buffer);
+ dma->this_buffer = buf;
+
+ atomic_add(length, &dma->total_bytes);
+ atomic_inc(&dma->total_dmas);
+
+ if (!buf->while_locked && !dev->context_flag && !locked) {
+ if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ DRM_ERROR("\n");
+ }
+ }
+cleanup:
+
+ clear_bit(0, &dev->dma_flag);
+
+#if DRM_DMA_HISTOGRAM
+ getnanotime(&dma_stop);
+ timespecsub(&dma_stop, &dma_start);
+ atomic_inc(&dev->histo.ctx[drm_histogram_slot(&dma_stop)]);
+#endif
+
+ return retcode;
+}
+
+static void gamma_dma_schedule_wrapper(void *dev)
+{
+ gamma_dma_schedule(dev, 0);
+}
+
+int gamma_dma_schedule(drm_device_t *dev, int locked)
+{
+ int next;
+ drm_queue_t *q;
+ drm_buf_t *buf;
+ int retcode = 0;
+ int processed = 0;
+ int missed;
+ int expire = 20;
+ drm_device_dma_t *dma = dev->dma;
+#if DRM_DMA_HISTOGRAM
+ struct timespec schedule_start;
+#endif
+
+ if (test_and_set_bit(0, &dev->interrupt_flag)) {
+ /* Not reentrant */
+ atomic_inc(&dma->total_missed_sched);
+ return EBUSY;
+ }
+ missed = atomic_read(&dma->total_missed_sched);
+
+#if DRM_DMA_HISTOGRAM
+ getnanotime(&schedule_start);
+#endif
+
+again:
+ if (dev->context_flag) {
+ clear_bit(0, &dev->interrupt_flag);
+ return EBUSY;
+ }
+ if (dma->next_buffer) {
+ /* Unsent buffer that was previously
+ selected, but that couldn't be sent
+ because the lock could not be obtained
+ or the DMA engine wasn't ready. Try
+ again. */
+ atomic_inc(&dma->total_tried);
+ if (!(retcode = gamma_do_dma(dev, locked))) {
+ atomic_inc(&dma->total_hit);
+ ++processed;
+ }
+ } else {
+ do {
+ next = drm_select_queue(dev,
+ gamma_dma_schedule_wrapper);
+ if (next >= 0) {
+ q = dev->queuelist[next];
+ buf = drm_waitlist_get(&q->waitlist);
+ dma->next_buffer = buf;
+ dma->next_queue = q;
+ if (buf && buf->list == DRM_LIST_RECLAIM) {
+ drm_clear_next_buffer(dev);
+ drm_free_buffer(dev, buf);
+ }
+ }
+ } while (next >= 0 && !dma->next_buffer);
+ if (dma->next_buffer) {
+ if (!(retcode = gamma_do_dma(dev, locked))) {
+ ++processed;
+ }
+ }
+ }
+
+ if (--expire) {
+ if (missed != atomic_read(&dma->total_missed_sched)) {
+ atomic_inc(&dma->total_lost);
+ if (gamma_dma_is_ready(dev)) goto again;
+ }
+ if (processed && gamma_dma_is_ready(dev)) {
+ atomic_inc(&dma->total_lost);
+ processed = 0;
+ goto again;
+ }
+ }
+
+ clear_bit(0, &dev->interrupt_flag);
+
+#if DRM_DMA_HISTOGRAM
+ {
+ struct timespec ts;
+ getnanotime(&ts);
+ timespecsub(&ts, &schedule_start);
+ atomic_inc(&dev->histo.schedule[drm_histogram_slot(&ts)]);
+ }
+#endif
+ return retcode;
+}
+
+static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d)
+{
+ struct proc *p = curproc;
+ unsigned long address;
+ unsigned long length;
+ int must_free = 0;
+ int retcode = 0;
+ int i;
+ int idx;
+ drm_buf_t *buf;
+ drm_buf_t *last_buf = NULL;
+ drm_device_dma_t *dma = dev->dma;
+ static int never;
+
+ /* Turn off interrupt handling */
+ while (test_and_set_bit(0, &dev->interrupt_flag)) {
+ retcode = tsleep(&never, PZERO|PCATCH, "gamp1", 1);
+ if (retcode)
+ return retcode;
+ }
+ if (!(d->flags & _DRM_DMA_WHILE_LOCKED)) {
+ while (!drm_lock_take(&dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ retcode = tsleep(&never, PZERO|PCATCH, "gamp2", 1);
+ if (retcode)
+ return retcode;
+ }
+ ++must_free;
+ }
+ atomic_inc(&dma->total_prio);
+
+ for (i = 0; i < d->send_count; i++) {
+ idx = d->send_indices[i];
+ if (idx < 0 || idx >= dma->buf_count) {
+ DRM_ERROR("Index %d (of %d max)\n",
+ d->send_indices[i], dma->buf_count - 1);
+ continue;
+ }
+ buf = dma->buflist[ idx ];
+ if (buf->pid != p->p_pid) {
+ DRM_ERROR("Process %d using buffer owned by %d\n",
+ p->p_pid, buf->pid);
+ retcode = EINVAL;
+ goto cleanup;
+ }
+ if (buf->list != DRM_LIST_NONE) {
+ DRM_ERROR("Process %d using %d's buffer on list %d\n",
+ p->p_pid, buf->pid, buf->list);
+ retcode = EINVAL;
+ goto cleanup;
+ }
+ /* This isn't a race condition on
+ buf->list, since our concern is the
+ buffer reclaim during the time the
+ process closes the /dev/drm? handle, so
+ it can't also be doing DMA. */
+ buf->list = DRM_LIST_PRIO;
+ buf->used = d->send_sizes[i];
+ buf->context = d->context;
+ buf->while_locked = d->flags & _DRM_DMA_WHILE_LOCKED;
+ address = (unsigned long)buf->address;
+ length = buf->used;
+ if (!length) {
+ DRM_ERROR("0 length buffer\n");
+ }
+ if (buf->pending) {
+ DRM_ERROR("Sending pending buffer:"
+ " buffer %d, offset %d\n",
+ d->send_indices[i], i);
+ retcode = EINVAL;
+ goto cleanup;
+ }
+ if (buf->waiting) {
+ DRM_ERROR("Sending waiting buffer:"
+ " buffer %d, offset %d\n",
+ d->send_indices[i], i);
+ retcode = EINVAL;
+ goto cleanup;
+ }
+ buf->pending = 1;
+
+ if (dev->last_context != buf->context
+ && !(dev->queuelist[buf->context]->flags
+ & _DRM_CONTEXT_PRESERVED)) {
+ atomic_inc(&dev->context_wait);
+ /* PRE: dev->last_context != buf->context */
+ drm_context_switch(dev, dev->last_context,
+ buf->context);
+ /* POST: we will wait for the context
+ switch and will dispatch on a later call
+ when dev->last_context == buf->context.
+ NOTE WE HOLD THE LOCK THROUGHOUT THIS
+ TIME! */
+ retcode = tsleep(&dev->context_wait, PZERO|PCATCH,
+ "gamctx", 0);
+ atomic_dec(&dev->context_wait);
+ if (retcode)
+ goto cleanup;
+ if (dev->last_context != buf->context) {
+ DRM_ERROR("Context mismatch: %d %d\n",
+ dev->last_context,
+ buf->context);
+ }
+ }
+
+#if DRM_DMA_HISTOGRAM
+ getnanotime(&buf->time_queued);
+ buf->time_dispatched = buf->time_queued;
+#endif
+ gamma_dma_dispatch(dev, address, length);
+ atomic_add(length, &dma->total_bytes);
+ atomic_inc(&dma->total_dmas);
+
+ if (last_buf) {
+ drm_free_buffer(dev, last_buf);
+ }
+ last_buf = buf;
+ }
+
+
+cleanup:
+ if (last_buf) {
+ gamma_dma_ready(dev);
+ drm_free_buffer(dev, last_buf);
+ }
+
+ if (must_free && !dev->context_flag) {
+ if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ DRM_ERROR("\n");
+ }
+ }
+ clear_bit(0, &dev->interrupt_flag);
+ return retcode;
+}
+
+static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d)
+{
+ struct proc *p = curproc;
+ drm_buf_t *last_buf = NULL;
+ int retcode = 0;
+ drm_device_dma_t *dma = dev->dma;
+
+
+ if ((retcode = drm_dma_enqueue(dev, d))) {
+ return retcode;
+ }
+
+ gamma_dma_schedule(dev, 0);
+
+ if (d->flags & _DRM_DMA_BLOCK) {
+ last_buf = dma->buflist[d->send_indices[d->send_count-1]];
+ atomic_inc(&last_buf->dma_wait);
+ }
+
+ if (d->flags & _DRM_DMA_BLOCK) {
+ DRM_DEBUG("%d waiting\n", p->p_pid);
+ for (;;) {
+ retcode = tsleep(&last_buf->dma_wait, PZERO|PCATCH,
+ "gamdw", 0);
+ if (!last_buf->waiting
+ && !last_buf->pending)
+ break; /* finished */
+ if (retcode)
+ break;
+ }
+
+ DRM_DEBUG("%d running\n", p->p_pid);
+ atomic_dec(&last_buf->dma_wait);
+ if (!retcode
+ || (last_buf->list==DRM_LIST_PEND && !last_buf->pending)) {
+ if (!last_buf->dma_wait) {
+ drm_free_buffer(dev, last_buf);
+ }
+ }
+ if (retcode) {
+ DRM_ERROR("ctx%d w%d p%d c%d i%d l%d %d/%d\n",
+ d->context,
+ last_buf->waiting,
+ last_buf->pending,
+ DRM_WAITCOUNT(dev, d->context),
+ last_buf->idx,
+ last_buf->list,
+ last_buf->pid,
+ p->p_pid);
+ }
+ }
+ return retcode;
+}
+
+int gamma_dma(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_device_dma_t *dma = dev->dma;
+ int retcode = 0;
+ drm_dma_t d;
+
+ d = *(drm_dma_t *) data;
+ DRM_DEBUG("%d %d: %d send, %d req\n",
+ p->p_pid, d.context, d.send_count, d.request_count);
+
+ if (d.context == DRM_KERNEL_CONTEXT || d.context >= dev->queue_slots) {
+ DRM_ERROR("Process %d using context %d\n",
+ p->p_pid, d.context);
+ return EINVAL;
+ }
+ if (d.send_count < 0 || d.send_count > dma->buf_count) {
+ DRM_ERROR("Process %d trying to send %d buffers (of %d max)\n",
+ p->p_pid, d.send_count, dma->buf_count);
+ return EINVAL;
+ }
+ if (d.request_count < 0 || d.request_count > dma->buf_count) {
+ DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
+ p->p_pid, d.request_count, dma->buf_count);
+ return EINVAL;
+ }
+
+ if (d.send_count) {
+ if (d.flags & _DRM_DMA_PRIORITY)
+ retcode = gamma_dma_priority(dev, &d);
+ else
+ retcode = gamma_dma_send_buffers(dev, &d);
+ }
+
+ d.granted_count = 0;
+
+ if (!retcode && d.request_count) {
+ retcode = drm_dma_get_buffers(dev, &d);
+ }
+
+ DRM_DEBUG("%d returning, granted = %d\n",
+ p->p_pid, d.granted_count);
+ *(drm_dma_t *) data = d;
+
+ return retcode;
+}
+
+int gamma_irq_install(drm_device_t *dev, int irq)
+{
+ int rid;
+ int retcode;
+
+ if (!irq) return EINVAL;
+
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc);
+ if (dev->irq) {
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+ return EBUSY;
+ }
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+
+ DRM_DEBUG("%d\n", irq);
+
+ dev->context_flag = 0;
+ dev->interrupt_flag = 0;
+ dev->dma_flag = 0;
+
+ dev->dma->next_buffer = NULL;
+ dev->dma->next_queue = NULL;
+ dev->dma->this_buffer = NULL;
+
+#if 0
+ dev->tq.next = NULL;
+ dev->tq.sync = 0;
+ dev->tq.routine = gamma_dma_schedule_tq_wrapper;
+ dev->tq.data = dev;
+#endif
+ /* Before installing handler */
+ GAMMA_WRITE(GAMMA_GCOMMANDMODE, 0);
+ GAMMA_WRITE(GAMMA_GDMACONTROL, 0);
+
+ /* Install handler */
+ rid = 0;
+ dev->irq = bus_alloc_resource(dev->device, SYS_RES_IRQ, &rid,
+ 0, ~0, 1, RF_SHAREABLE);
+ if (!dev->irq)
+ return ENOENT;
+
+ retcode = bus_setup_intr(dev->device, dev->irq, INTR_TYPE_TTY,
+ gamma_dma_service, dev, &dev->irqh);
+ if (retcode) {
+ bus_release_resource(dev->device, SYS_RES_IRQ, 0, dev->irq);
+ dev->irq = 0;
+ return retcode;
+ }
+
+ /* After installing handler */
+ GAMMA_WRITE(GAMMA_GINTENABLE, 0x2001);
+ GAMMA_WRITE(GAMMA_COMMANDINTENABLE, 0x0008);
+ GAMMA_WRITE(GAMMA_GDELAYTIMER, 0x39090);
+
+ return 0;
+}
+
+int gamma_irq_uninstall(drm_device_t *dev)
+{
+ if (!dev->irq)
+ return EINVAL;
+
+ DRM_DEBUG("%ld\n", rman_get_start(dev->irq));
+
+ GAMMA_WRITE(GAMMA_GDELAYTIMER, 0);
+ GAMMA_WRITE(GAMMA_COMMANDINTENABLE, 0);
+ GAMMA_WRITE(GAMMA_GINTENABLE, 0);
+
+ bus_teardown_intr(dev->device, dev->irq, dev->irqh);
+ bus_release_resource(dev->device, SYS_RES_IRQ, 0, dev->irq);
+ dev->irq = 0;
+
+ return 0;
+}
+
+
+int gamma_control(dev_t kdev, u_long cmd, caddr_t data,
+ int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_control_t ctl;
+ int retcode;
+
+ ctl = *(drm_control_t *) data;
+
+ switch (ctl.func) {
+ case DRM_INST_HANDLER:
+ if ((retcode = gamma_irq_install(dev, ctl.irq)))
+ return retcode;
+ break;
+ case DRM_UNINST_HANDLER:
+ if ((retcode = gamma_irq_uninstall(dev)))
+ return retcode;
+ break;
+ default:
+ return EINVAL;
+ }
+ return 0;
+}
+
+int gamma_lock(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ int ret = 0;
+ drm_lock_t lock;
+ drm_queue_t *q;
+#if DRM_DMA_HISTOGRAM
+ struct timespec start;
+
+ getnanotime(&start);
+ dev->lck_start = start;
+#endif
+
+ lock = *(drm_lock_t *) data;
+
+ if (lock.context == DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("Process %d using kernel context %d\n",
+ p->p_pid, lock.context);
+ return EINVAL;
+ }
+
+ DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
+ lock.context, p->p_pid, dev->lock.hw_lock->lock,
+ lock.flags);
+
+ if (lock.context < 0 || lock.context >= dev->queue_count)
+ return EINVAL;
+ q = dev->queuelist[lock.context];
+
+ ret = drm_flush_block_and_flush(dev, lock.context, lock.flags);
+
+ if (!ret) {
+ if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
+ != lock.context) {
+ long j = ticks - dev->lock.lock_time;
+
+ if (j > 0 && j <= DRM_LOCK_SLICE) {
+ /* Can't take lock if we just had it and
+ there is contention. */
+ static int never;
+ ret = tsleep(&never, PZERO|PCATCH,
+ "gaml1", j);
+ if (ret)
+ return ret;
+ }
+ }
+ atomic_inc(&dev->lock.lock_queue);
+ for (;;) {
+ if (!dev->lock.hw_lock) {
+ /* Device has been unregistered */
+ ret = EINTR;
+ break;
+ }
+ if (drm_lock_take(&dev->lock.hw_lock->lock,
+ lock.context)) {
+ dev->lock.pid = p->p_pid;
+ dev->lock.lock_time = ticks;
+ atomic_inc(&dev->total_locks);
+ atomic_inc(&q->total_locks);
+ break; /* Got lock */
+ }
+
+ /* Contention */
+ atomic_inc(&dev->total_sleeps);
+ ret = tsleep(&dev->lock.lock_queue, PZERO|PCATCH,
+ "gaml2", 0);
+ if (ret)
+ break;
+ }
+ atomic_dec(&dev->lock.lock_queue);
+ }
+
+ drm_flush_unblock(dev, lock.context, lock.flags); /* cleanup phase */
+
+ if (!ret) {
+ if (lock.flags & _DRM_LOCK_READY)
+ gamma_dma_ready(dev);
+ if (lock.flags & _DRM_LOCK_QUIESCENT)
+ gamma_dma_quiescent(dev);
+ }
+ DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
+
+#if DRM_DMA_HISTOGRAM
+ {
+ struct timespec ts;
+ getnanotime(&ts);
+ timespecsub(&ts, &start);
+ atomic_inc(&dev->histo.lacq[drm_histogram_slot(&ts)]);
+ }
+#endif
+
+ return ret;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma/gamma_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma/gamma_drv.c
new file mode 100644
index 000000000..fe71737a5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma/gamma_drv.c
@@ -0,0 +1,574 @@
+/* gamma.c -- 3dlabs GMX 2000 driver -*- c -*-
+ * Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com
+ * Revised: Tue Oct 12 08:51:36 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c,v 1.17 1999/08/30 13:05:00 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c,v 1.1 1999/09/25 14:38:00 dawes Exp $
+ *
+ */
+
+#include "drmP.h"
+#include "gamma_drv.h"
+
+#include <pci/pcivar.h>
+
+MODULE_DEPEND(gamma, drm, 1, 1, 1);
+
+static int gamma_init(device_t nbdev);
+static void gamma_cleanup(device_t nbdev);
+
+static int gamma_probe(device_t dev)
+{
+ const char *s = 0;
+
+ switch (pci_get_devid(dev)) {
+ case 0x00083d3d:
+ s = "3D Labs Gamma graphics accelerator";
+ break;
+ }
+
+ if (s) {
+ device_set_desc(dev, s);
+ return 0;
+ }
+
+ return ENXIO;
+}
+
+static int gamma_attach(device_t dev)
+{
+ gamma_init(dev);
+ return 0;
+}
+
+static int gamma_detach(device_t dev)
+{
+ gamma_cleanup(dev);
+ return 0;
+}
+
+static device_method_t gamma_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, gamma_probe),
+ DEVMETHOD(device_attach, gamma_attach),
+ DEVMETHOD(device_detach, gamma_detach),
+
+ { 0, 0 }
+};
+
+static driver_t gamma_driver = {
+ "drm",
+ gamma_methods,
+ sizeof(drm_device_t),
+};
+
+static devclass_t gamma_devclass;
+#define GAMMA_SOFTC(unit) \
+ ((drm_device_t *) devclass_get_softc(gamma_devclass, unit))
+
+DRIVER_MODULE(if_gamma, pci, gamma_driver, gamma_devclass, 0, 0);
+
+#define GAMMA_NAME "gamma"
+#define GAMMA_DESC "3dlabs GMX 2000"
+#define GAMMA_DATE "19990830"
+#define GAMMA_MAJOR 0
+#define GAMMA_MINOR 0
+#define GAMMA_PATCHLEVEL 5
+
+#define CDEV_MAJOR 200
+
+static struct cdevsw gamma_cdevsw = {
+ /* open */ gamma_open,
+ /* close */ gamma_close,
+ /* read */ drm_read,
+ /* write */ drm_write,
+ /* ioctl */ gamma_ioctl,
+ /* poll */ nopoll,
+ /* mmap */ drm_mmap,
+ /* strategy */ nostrategy,
+ /* name */ "gamma",
+ /* maj */ CDEV_MAJOR,
+ /* dump */ nodump,
+ /* psize */ nopsize,
+ /* flags */ D_TTY | D_TRACKCLOSE,
+ /* bmaj */ -1
+};
+
+static drm_ioctl_desc_t gamma_ioctls[] = {
+ [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { gamma_version, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_busid, 0, 1 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_block, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { gamma_control, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { drm_addbufs, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { drm_mapbufs, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, 1, 0 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { drm_addctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { drm_rmctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { drm_modctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { drm_getctx, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { drm_switchctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { drm_newctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { drm_resctx, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { gamma_lock, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { gamma_unlock, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 },
+};
+#define GAMMA_IOCTL_COUNT DRM_ARRAY_SIZE(gamma_ioctls)
+
+static int gamma_setup(drm_device_t *dev)
+{
+ int i;
+
+ device_busy(dev->device);
+
+ atomic_set(&dev->ioctl_count, 0);
+ atomic_set(&dev->vma_count, 0);
+ dev->buf_use = 0;
+ atomic_set(&dev->buf_alloc, 0);
+
+ drm_dma_setup(dev);
+
+ atomic_set(&dev->total_open, 0);
+ atomic_set(&dev->total_close, 0);
+ atomic_set(&dev->total_ioctl, 0);
+ atomic_set(&dev->total_irq, 0);
+ atomic_set(&dev->total_ctx, 0);
+ atomic_set(&dev->total_locks, 0);
+ atomic_set(&dev->total_unlocks, 0);
+ atomic_set(&dev->total_contends, 0);
+ atomic_set(&dev->total_sleeps, 0);
+
+ for (i = 0; i < DRM_HASH_SIZE; i++) {
+ dev->magiclist[i].head = NULL;
+ dev->magiclist[i].tail = NULL;
+ }
+ dev->maplist = NULL;
+ dev->map_count = 0;
+ dev->vmalist = NULL;
+ dev->lock.hw_lock = NULL;
+ dev->lock.lock_queue = 0;
+ dev->queue_count = 0;
+ dev->queue_reserved = 0;
+ dev->queue_slots = 0;
+ dev->queuelist = NULL;
+ dev->irq = 0;
+ dev->context_flag = 0;
+ dev->interrupt_flag = 0;
+ dev->dma_flag = 0;
+ dev->last_context = 0;
+ dev->last_switch = 0;
+ dev->last_checked = 0;
+ callout_init(&dev->timer);
+ dev->context_wait = 0;
+#if DRM_DMA_HISTO
+ memset(&dev->histo, 0, sizeof(dev->histo));
+#endif
+ timespecclear(&dev->ctx_start);
+ timespecclear(&dev->lck_start);
+
+ dev->buf_rp = dev->buf;
+ dev->buf_wp = dev->buf;
+ dev->buf_end = dev->buf + DRM_BSZ;
+ dev->buf_sigio = NULL;
+
+ DRM_DEBUG("\n");
+
+ /* The kernel's context could be created here, but is now created
+ in drm_dma_enqueue. This is more resource-efficient for
+ hardware that does not do DMA, but may mean that
+ drm_select_queue fails between the time the interrupt is
+ initialized and the time the queues are initialized. */
+
+ return 0;
+}
+
+
+static int
+gamma_takedown(drm_device_t *dev)
+{
+ int i;
+ drm_magic_entry_t *pt, *next;
+ drm_map_t *map;
+ drm_vma_entry_t *vma, *vma_next;
+
+ DRM_DEBUG("\n");
+
+ if (dev->irq) gamma_irq_uninstall(dev);
+
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc);
+ callout_stop(&dev->timer);
+
+ if (dev->devname) {
+ drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
+ dev->devname = NULL;
+ }
+
+ if (dev->unique) {
+ drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
+ dev->unique = NULL;
+ dev->unique_len = 0;
+ }
+ /* Clear pid list */
+ for (i = 0; i < DRM_HASH_SIZE; i++) {
+ for (pt = dev->magiclist[i].head; pt; pt = next) {
+ next = pt->next;
+ drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
+ }
+ dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
+ }
+
+ /* Clear vma list (only built for debugging) */
+ if (dev->vmalist) {
+ for (vma = dev->vmalist; vma; vma = vma_next) {
+ vma_next = vma->next;
+ drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
+ }
+ dev->vmalist = NULL;
+ }
+
+ /* Clear map area and mtrr information */
+ if (dev->maplist) {
+ for (i = 0; i < dev->map_count; i++) {
+ map = dev->maplist[i];
+ switch (map->type) {
+ case _DRM_REGISTERS:
+ case _DRM_FRAME_BUFFER:
+#ifdef CONFIG_MTRR
+ if (map->mtrr >= 0) {
+ int retcode;
+ retcode = mtrr_del(map->mtrr,
+ map->offset,
+ map->size);
+ DRM_DEBUG("mtrr_del = %d\n", retcode);
+ }
+#endif
+ drm_ioremapfree(map->handle, map->size);
+ break;
+ case _DRM_SHM:
+ drm_free_pages((unsigned long)map->handle,
+ drm_order(map->size)
+ - PAGE_SHIFT,
+ DRM_MEM_SAREA);
+ break;
+ }
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ }
+ drm_free(dev->maplist,
+ dev->map_count * sizeof(*dev->maplist),
+ DRM_MEM_MAPS);
+ dev->maplist = NULL;
+ dev->map_count = 0;
+ }
+
+ if (dev->queuelist) {
+ for (i = 0; i < dev->queue_count; i++) {
+ drm_waitlist_destroy(&dev->queuelist[i]->waitlist);
+ if (dev->queuelist[i]) {
+ drm_free(dev->queuelist[i],
+ sizeof(*dev->queuelist[0]),
+ DRM_MEM_QUEUES);
+ dev->queuelist[i] = NULL;
+ }
+ }
+ drm_free(dev->queuelist,
+ dev->queue_slots * sizeof(*dev->queuelist),
+ DRM_MEM_QUEUES);
+ dev->queuelist = NULL;
+ }
+
+ drm_dma_takedown(dev);
+
+ dev->queue_count = 0;
+ if (dev->lock.hw_lock) {
+ dev->lock.hw_lock = NULL; /* SHM removed */
+ dev->lock.pid = 0;
+ wakeup(&dev->lock.lock_queue);
+ }
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+
+ device_unbusy(dev->device);
+
+ return 0;
+}
+
+/* gamma_init is called via gamma_attach at module load time */
+
+static int
+gamma_init(device_t nbdev)
+{
+ drm_device_t *dev = device_get_softc(nbdev);
+
+ DRM_DEBUG("\n");
+
+ memset((void *)dev, 0, sizeof(*dev));
+ simple_lock_init(&dev->count_lock);
+ lockinit(&dev->dev_lock, PZERO, "drmlk", 0, 0);
+
+#if 0 /* XXX use getenv I guess */
+ drm_parse_options(gamma);
+#endif
+
+#if 0
+ if ((retcode = misc_register(&gamma_misc))) {
+ DRM_ERROR("Cannot register \"%s\"\n", GAMMA_NAME);
+ return retcode;
+ }
+#endif
+ dev->device = nbdev;
+ dev->devnode = make_dev(&gamma_cdevsw,
+ device_get_unit(nbdev),
+ DRM_DEV_UID,
+ DRM_DEV_GID,
+ DRM_DEV_MODE,
+ GAMMA_NAME);
+ dev->name = GAMMA_NAME;
+
+ drm_mem_init();
+ drm_sysctl_init(dev);
+
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+ GAMMA_NAME,
+ GAMMA_MAJOR,
+ GAMMA_MINOR,
+ GAMMA_PATCHLEVEL,
+ GAMMA_DATE,
+ device_get_unit(nbdev));
+
+ return 0;
+}
+
+/* gamma_cleanup is called via gamma_detach at module unload time. */
+
+static void
+gamma_cleanup(device_t nbdev)
+{
+ drm_device_t *dev = device_get_softc(nbdev);
+
+ DRM_DEBUG("\n");
+
+ drm_sysctl_cleanup(dev);
+#if 0
+ if (misc_deregister(&gamma_misc)) {
+ DRM_ERROR("Cannot unload module\n");
+ } else {
+ DRM_INFO("Module unloaded\n");
+ }
+#endif
+ device_busy(dev->device);
+ gamma_takedown(dev);
+}
+
+SYSUNINIT(gamma_cleanup, SI_SUB_DRIVERS, SI_ORDER_ANY, gamma_cleanup, 0);
+
+#if 0
+int gamma_version(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_version_t version;
+ int len;
+
+ copy_from_user_ret(&version,
+ (drm_version_t *)arg,
+ sizeof(version),
+ -EFAULT);
+
+#define DRM_COPY(name,value) \
+ len = strlen(value); \
+ if (len > name##_len) len = name##_len; \
+ name##_len = strlen(value); \
+ if (len && name) { \
+ copy_to_user_ret(name, value, len, -EFAULT); \
+ }
+
+ version.version_major = GAMMA_MAJOR;
+ version.version_minor = GAMMA_MINOR;
+ version.version_patchlevel = GAMMA_PATCHLEVEL;
+
+ DRM_COPY(version.name, GAMMA_NAME);
+ DRM_COPY(version.date, GAMMA_DATE);
+ DRM_COPY(version.desc, GAMMA_DESC);
+
+ copy_to_user_ret((drm_version_t *)arg,
+ &version,
+ sizeof(version),
+ -EFAULT);
+ return 0;
+}
+#endif
+
+int
+gamma_open(dev_t kdev, int flags, int fmt, struct proc *p)
+{
+ drm_device_t *dev = GAMMA_SOFTC(minor(kdev));
+ int retcode = 0;
+
+ DRM_DEBUG("open_count = %d\n", dev->open_count);
+
+ device_busy(dev->device);
+ if (!(retcode = drm_open_helper(kdev, flags, fmt, p, dev))) {
+ atomic_inc(&dev->total_open);
+ simple_lock(&dev->count_lock);
+ if (!dev->open_count++) {
+ simple_unlock(&dev->count_lock);
+ retcode = gamma_setup(dev);
+ }
+ simple_unlock(&dev->count_lock);
+ }
+ device_unbusy(dev->device);
+
+ return retcode;
+}
+
+int
+gamma_close(dev_t kdev, int flags, int fmt, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ int retcode = 0;
+
+ DRM_DEBUG("open_count = %d\n", dev->open_count);
+ if (!(retcode = drm_close(kdev, flags, fmt, p))) {
+ atomic_inc(&dev->total_close);
+ simple_lock(&dev->count_lock);
+ if (!--dev->open_count) {
+ if (atomic_read(&dev->ioctl_count) || dev->blocked) {
+ DRM_ERROR("Device busy: %d %d\n",
+ atomic_read(&dev->ioctl_count),
+ dev->blocked);
+ simple_unlock(&dev->count_lock);
+ return EBUSY;
+ }
+ simple_unlock(&dev->count_lock);
+ return gamma_takedown(dev);
+ }
+ simple_unlock(&dev->count_lock);
+ }
+ return retcode;
+}
+
+/* drm_ioctl is called whenever a process performs an ioctl on /dev/drm. */
+
+int
+gamma_ioctl(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ int nr = DRM_IOCTL_NR(cmd);
+ drm_device_t *dev = kdev->si_drv1;
+ drm_file_t *priv;
+ int retcode = 0;
+ drm_ioctl_desc_t *ioctl;
+ d_ioctl_t *func;
+
+ priv = drm_find_file_by_proc(dev, p);
+ if (!priv) {
+ DRM_DEBUG("can't find authenticator\n");
+ return EINVAL;
+ }
+
+ atomic_inc(&dev->ioctl_count);
+ atomic_inc(&dev->total_ioctl);
+ ++priv->ioctl_count;
+
+ DRM_DEBUG("pid = %d, cmd = 0x%02lx, nr = 0x%02x, auth = %d\n",
+ p->p_pid, cmd, nr, priv->authenticated);
+
+ switch (cmd) {
+ case FIOSETOWN:
+ return fsetown(*(int *)data, &dev->buf_sigio);
+
+ case FIOGETOWN:
+ *(int *) data = fgetown(dev->buf_sigio);
+ return 0;
+ }
+
+ if (nr >= GAMMA_IOCTL_COUNT) {
+ retcode = EINVAL;
+ } else {
+ ioctl = &gamma_ioctls[nr];
+ func = ioctl->func;
+
+ if (!func) {
+ DRM_DEBUG("no function\n");
+ retcode = EINVAL;
+ } else if ((ioctl->root_only && suser(p))
+ || (ioctl->auth_needed && !priv->authenticated)) {
+ retcode = EACCES;
+ } else {
+ retcode = (func)(kdev, cmd, data, flags, p);
+ }
+ }
+
+ atomic_dec(&dev->ioctl_count);
+ return retcode;
+}
+
+int gamma_unlock(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_lock_t *lockp = (drm_lock_t *) data;
+
+ if (lockp->context == DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("Process %d using kernel context %d\n",
+ p->p_pid, lockp->context);
+ return -EINVAL;
+ }
+
+ DRM_DEBUG("%d frees lock (%d holds)\n",
+ lockp->context,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+ atomic_inc(&dev->total_unlocks);
+ if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
+ atomic_inc(&dev->total_contends);
+ drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
+ gamma_dma_schedule(dev, 1);
+ if (!dev->context_flag) {
+ if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ DRM_ERROR("\n");
+ }
+ }
+
+#if DRM_DMA_HISTOGRAM
+ {
+ struct timespec ts;
+ getnanotime(&ts);
+ timespecsub(&ts, &dev->lck_start);
+ atomic_inc(&dev->histo.lhld[drm_histogram_slot(&ts)]);
+ }
+#endif
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma/gamma_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma/gamma_drv.h
new file mode 100644
index 000000000..e48882207
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/gamma/gamma_drv.h
@@ -0,0 +1,50 @@
+/* gamma_drv.h -- Private header for 3dlabs GMX 2000 driver -*- c -*-
+ * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
+ * Revised: Fri Aug 20 09:24:27 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h,v 1.4 1999/08/30 13:05:00 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h,v 1.1 1999/09/25 14:38:00 dawes Exp $
+ *
+ */
+
+#ifndef _GAMMA_DRV_H_
+#define _GAMMA_DRV_H_
+
+ /* gamma_drv.c */
+extern d_open_t gamma_open;
+extern d_close_t gamma_close;
+extern d_ioctl_t gamma_ioctl;
+extern d_ioctl_t gamma_version;
+extern d_ioctl_t gamma_dma;
+extern d_ioctl_t gamma_lock;
+extern d_ioctl_t gamma_unlock;
+extern d_ioctl_t gamma_control;
+
+ /* gamma_dma.c */
+extern int gamma_dma_schedule(drm_device_t *dev, int locked);
+extern int gamma_irq_install(drm_device_t *dev, int irq);
+extern int gamma_irq_uninstall(drm_device_t *dev);
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/i810_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/i810_drm.h
new file mode 100644
index 000000000..4c8e09f6a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/i810_drm.h
@@ -0,0 +1,188 @@
+#ifndef _I810_DRM_H_
+#define _I810_DRM_H_
+
+/* WARNING: These defines must be the same as what the Xserver uses.
+ * if you change them, you must change the defines in the Xserver.
+ */
+
+#ifndef _I810_DEFINES_
+#define _I810_DEFINES_
+
+#define I810_DMA_BUF_ORDER 12
+#define I810_DMA_BUF_SZ (1<<I810_DMA_BUF_ORDER)
+#define I810_DMA_BUF_NR 256
+#define I810_NR_SAREA_CLIPRECTS 8
+
+/* Each region is a minimum of 64k, and there are at most 64 of them.
+ */
+#define I810_NR_TEX_REGIONS 64
+#define I810_LOG_MIN_TEX_REGION_SIZE 16
+#endif
+
+#define I810_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */
+#define I810_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */
+#define I810_UPLOAD_CTX 0x4
+#define I810_UPLOAD_BUFFERS 0x8
+#define I810_UPLOAD_TEX0 0x10
+#define I810_UPLOAD_TEX1 0x20
+#define I810_UPLOAD_CLIPRECTS 0x40
+
+
+/* Indices into buf.Setup where various bits of state are mirrored per
+ * context and per buffer. These can be fired at the card as a unit,
+ * or in a piecewise fashion as required.
+ */
+
+/* Destbuffer state
+ * - backbuffer linear offset and pitch -- invarient in the current dri
+ * - zbuffer linear offset and pitch -- also invarient
+ * - drawing origin in back and depth buffers.
+ *
+ * Keep the depth/back buffer state here to acommodate private buffers
+ * in the future.
+ */
+#define I810_DESTREG_DI0 0 /* CMD_OP_DESTBUFFER_INFO (2 dwords) */
+#define I810_DESTREG_DI1 1
+#define I810_DESTREG_DV0 2 /* GFX_OP_DESTBUFFER_VARS (2 dwords) */
+#define I810_DESTREG_DV1 3
+#define I810_DESTREG_DR0 4 /* GFX_OP_DRAWRECT_INFO (4 dwords) */
+#define I810_DESTREG_DR1 5
+#define I810_DESTREG_DR2 6
+#define I810_DESTREG_DR3 7
+#define I810_DESTREG_DR4 8
+#define I810_DEST_SETUP_SIZE 10
+
+/* Context state
+ */
+#define I810_CTXREG_CF0 0 /* GFX_OP_COLOR_FACTOR */
+#define I810_CTXREG_CF1 1
+#define I810_CTXREG_ST0 2 /* GFX_OP_STIPPLE */
+#define I810_CTXREG_ST1 3
+#define I810_CTXREG_VF 4 /* GFX_OP_VERTEX_FMT */
+#define I810_CTXREG_MT 5 /* GFX_OP_MAP_TEXELS */
+#define I810_CTXREG_MC0 6 /* GFX_OP_MAP_COLOR_STAGES - stage 0 */
+#define I810_CTXREG_MC1 7 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */
+#define I810_CTXREG_MC2 8 /* GFX_OP_MAP_COLOR_STAGES - stage 2 */
+#define I810_CTXREG_MA0 9 /* GFX_OP_MAP_ALPHA_STAGES - stage 0 */
+#define I810_CTXREG_MA1 10 /* GFX_OP_MAP_ALPHA_STAGES - stage 1 */
+#define I810_CTXREG_MA2 11 /* GFX_OP_MAP_ALPHA_STAGES - stage 2 */
+#define I810_CTXREG_SDM 12 /* GFX_OP_SRC_DEST_MONO */
+#define I810_CTXREG_FOG 13 /* GFX_OP_FOG_COLOR */
+#define I810_CTXREG_B1 14 /* GFX_OP_BOOL_1 */
+#define I810_CTXREG_B2 15 /* GFX_OP_BOOL_2 */
+#define I810_CTXREG_LCS 16 /* GFX_OP_LINEWIDTH_CULL_SHADE_MODE */
+#define I810_CTXREG_PV 17 /* GFX_OP_PV_RULE -- Invarient! */
+#define I810_CTXREG_ZA 18 /* GFX_OP_ZBIAS_ALPHAFUNC */
+#define I810_CTXREG_AA 19 /* GFX_OP_ANTIALIAS */
+#define I810_CTX_SETUP_SIZE 20
+
+/* Texture state (per tex unit)
+ */
+#define I810_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (4 dwords) */
+#define I810_TEXREG_MI1 1
+#define I810_TEXREG_MI2 2
+#define I810_TEXREG_MI3 3
+#define I810_TEXREG_MF 4 /* GFX_OP_MAP_FILTER */
+#define I810_TEXREG_MLC 5 /* GFX_OP_MAP_LOD_CTL */
+#define I810_TEXREG_MLL 6 /* GFX_OP_MAP_LOD_LIMITS */
+#define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */
+#define I810_TEX_SETUP_SIZE 8
+
+#define I810_FRONT 0x1
+#define I810_BACK 0x2
+#define I810_DEPTH 0x4
+
+
+typedef struct _drm_i810_init {
+ enum {
+ I810_INIT_DMA = 0x01,
+ I810_CLEANUP_DMA = 0x02
+ } func;
+ int ring_map_idx;
+ int buffer_map_idx;
+ int sarea_priv_offset;
+ unsigned int ring_start;
+ unsigned int ring_end;
+ unsigned int ring_size;
+ unsigned int front_offset;
+ unsigned int back_offset;
+ unsigned int depth_offset;
+ unsigned int w;
+ unsigned int h;
+ unsigned int pitch;
+ unsigned int pitch_bits;
+} drm_i810_init_t;
+
+/* Warning: If you change the SAREA structure you must change the Xserver
+ * structure as well */
+
+typedef struct _drm_i810_tex_region {
+ unsigned char next, prev; /* indices to form a circular LRU */
+ unsigned char in_use; /* owned by a client, or free? */
+ int age; /* tracked by clients to update local LRU's */
+} drm_i810_tex_region_t;
+
+typedef struct _drm_i810_sarea {
+ unsigned int ContextState[I810_CTX_SETUP_SIZE];
+ unsigned int BufferState[I810_DEST_SETUP_SIZE];
+ unsigned int TexState[2][I810_TEX_SETUP_SIZE];
+ unsigned int dirty;
+
+ unsigned int nbox;
+ drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS];
+
+ /* Maintain an LRU of contiguous regions of texture space. If
+ * you think you own a region of texture memory, and it has an
+ * age different to the one you set, then you are mistaken and
+ * it has been stolen by another client. If global texAge
+ * hasn't changed, there is no need to walk the list.
+ *
+ * These regions can be used as a proxy for the fine-grained
+ * texture information of other clients - by maintaining them
+ * in the same lru which is used to age their own textures,
+ * clients have an approximate lru for the whole of global
+ * texture space, and can make informed decisions as to which
+ * areas to kick out. There is no need to choose whether to
+ * kick out your own texture or someone else's - simply eject
+ * them all in LRU order.
+ */
+
+ drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS+1];
+ /* Last elt is sentinal */
+ int texAge; /* last time texture was uploaded */
+ int last_enqueue; /* last time a buffer was enqueued */
+ int last_dispatch; /* age of the most recently dispatched buffer */
+ int last_quiescent; /* */
+ int ctxOwner; /* last context to upload state */
+
+ int vertex_prim;
+
+} drm_i810_sarea_t;
+
+typedef struct _drm_i810_clear {
+ int clear_color;
+ int clear_depth;
+ int flags;
+} drm_i810_clear_t;
+
+
+
+/* These may be placeholders if we have more cliprects than
+ * I810_NR_SAREA_CLIPRECTS. In that case, the client sets discard to
+ * false, indicating that the buffer will be dispatched again with a
+ * new set of cliprects.
+ */
+typedef struct _drm_i810_vertex {
+ int idx; /* buffer index */
+ int used; /* nr bytes in use */
+ int discard; /* client is finished with the buffer? */
+} drm_i810_vertex_t;
+
+typedef struct drm_i810_dma {
+ void *virtual;
+ int request_idx;
+ int request_size;
+ int granted;
+} drm_i810_dma_t;
+
+#endif /* _I810_DRM_H_ */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/mga_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/mga_drm.h
new file mode 100644
index 000000000..8bfa2b974
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/mga_drm.h
@@ -0,0 +1,269 @@
+/* mga_drm.h -- Public header for the Matrox g200/g400 driver
+ * Created: Tue Jan 25 01:50:01 1999 by jhartmann@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Jeff Hartmann <jhartmann@precisioninsight.com>
+ * Keith Whitwell <keithw@precisioninsight.com>
+ *
+ * $XFree86$
+ */
+
+#ifndef _MGA_DRM_H_
+#define _MGA_DRM_H_
+
+/* WARNING: If you change any of these defines, make sure to change the
+ * defines in the Xserver file (xf86drmMga.h)
+ */
+#ifndef _MGA_DEFINES_
+#define _MGA_DEFINES_
+
+#define MGA_F 0x1 /* fog */
+#define MGA_A 0x2 /* alpha */
+#define MGA_S 0x4 /* specular */
+#define MGA_T2 0x8 /* multitexture */
+
+#define MGA_WARP_TGZ 0
+#define MGA_WARP_TGZF (MGA_F)
+#define MGA_WARP_TGZA (MGA_A)
+#define MGA_WARP_TGZAF (MGA_F|MGA_A)
+#define MGA_WARP_TGZS (MGA_S)
+#define MGA_WARP_TGZSF (MGA_S|MGA_F)
+#define MGA_WARP_TGZSA (MGA_S|MGA_A)
+#define MGA_WARP_TGZSAF (MGA_S|MGA_F|MGA_A)
+#define MGA_WARP_T2GZ (MGA_T2)
+#define MGA_WARP_T2GZF (MGA_T2|MGA_F)
+#define MGA_WARP_T2GZA (MGA_T2|MGA_A)
+#define MGA_WARP_T2GZAF (MGA_T2|MGA_A|MGA_F)
+#define MGA_WARP_T2GZS (MGA_T2|MGA_S)
+#define MGA_WARP_T2GZSF (MGA_T2|MGA_S|MGA_F)
+#define MGA_WARP_T2GZSA (MGA_T2|MGA_S|MGA_A)
+#define MGA_WARP_T2GZSAF (MGA_T2|MGA_S|MGA_F|MGA_A)
+
+#define MGA_MAX_G400_PIPES 16
+#define MGA_MAX_G200_PIPES 8 /* no multitex */
+#define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES
+
+#define MGA_CARD_TYPE_G200 1
+#define MGA_CARD_TYPE_G400 2
+
+#define MGA_FRONT 0x1
+#define MGA_BACK 0x2
+#define MGA_DEPTH 0x4
+
+/* 3d state excluding texture units:
+ */
+#define MGA_CTXREG_DSTORG 0 /* validated */
+#define MGA_CTXREG_MACCESS 1
+#define MGA_CTXREG_PLNWT 2
+#define MGA_CTXREG_DWGCTL 3
+#define MGA_CTXREG_ALPHACTRL 4
+#define MGA_CTXREG_FOGCOLOR 5
+#define MGA_CTXREG_WFLAG 6
+#define MGA_CTXREG_TDUAL0 7
+#define MGA_CTXREG_TDUAL1 8
+#define MGA_CTXREG_FCOL 9
+#define MGA_CTX_SETUP_SIZE 10
+
+/* 2d state
+ */
+#define MGA_2DREG_PITCH 0
+#define MGA_2D_SETUP_SIZE 1
+
+/* Each texture unit has a state:
+ */
+#define MGA_TEXREG_CTL 0
+#define MGA_TEXREG_CTL2 1
+#define MGA_TEXREG_FILTER 2
+#define MGA_TEXREG_BORDERCOL 3
+#define MGA_TEXREG_ORG 4 /* validated */
+#define MGA_TEXREG_ORG1 5
+#define MGA_TEXREG_ORG2 6
+#define MGA_TEXREG_ORG3 7
+#define MGA_TEXREG_ORG4 8
+#define MGA_TEXREG_WIDTH 9
+#define MGA_TEXREG_HEIGHT 10
+#define MGA_TEX_SETUP_SIZE 11
+
+/* What needs to be changed for the current vertex dma buffer?
+ */
+#define MGA_UPLOAD_CTX 0x1
+#define MGA_UPLOAD_TEX0 0x2
+#define MGA_UPLOAD_TEX1 0x4
+#define MGA_UPLOAD_PIPE 0x8
+#define MGA_UPLOAD_TEX0IMAGE 0x10 /* handled client-side */
+#define MGA_UPLOAD_TEX1IMAGE 0x20 /* handled client-side */
+#define MGA_UPLOAD_2D 0x40
+#define MGA_WAIT_AGE 0x80 /* handled client-side */
+#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */
+#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock
+ quiescent */
+
+/* 32 buffers of 64k each, total 2 meg.
+ */
+#define MGA_DMA_BUF_ORDER 16
+#define MGA_DMA_BUF_SZ (1<<MGA_DMA_BUF_ORDER)
+#define MGA_DMA_BUF_NR 31
+
+/* Keep these small for testing.
+ */
+#define MGA_NR_SAREA_CLIPRECTS 8
+
+/* 2 heaps (1 for card, 1 for agp), each divided into upto 128
+ * regions, subject to a minimum region size of (1<<16) == 64k.
+ *
+ * Clients may subdivide regions internally, but when sharing between
+ * clients, the region size is the minimum granularity.
+ */
+
+#define MGA_CARD_HEAP 0
+#define MGA_AGP_HEAP 1
+#define MGA_NR_TEX_HEAPS 2
+#define MGA_NR_TEX_REGIONS 16
+#define MGA_LOG_MIN_TEX_REGION_SIZE 16
+#endif
+
+typedef struct _drm_mga_warp_index {
+ int installed;
+ unsigned long phys_addr;
+ int size;
+} drm_mga_warp_index_t;
+
+typedef struct drm_mga_init {
+ enum {
+ MGA_INIT_DMA = 0x01,
+ MGA_CLEANUP_DMA = 0x02
+ } func;
+ int reserved_map_agpstart;
+ int reserved_map_idx;
+ int buffer_map_idx;
+ int sarea_priv_offset;
+ int primary_size;
+ int warp_ucode_size;
+ unsigned int frontOffset;
+ unsigned int backOffset;
+ unsigned int depthOffset;
+ unsigned int textureOffset;
+ unsigned int textureSize;
+ unsigned int agpTextureOffset;
+ unsigned int agpTextureSize;
+ unsigned int cpp;
+ unsigned int stride;
+ int sgram;
+ int chipset;
+ drm_mga_warp_index_t WarpIndex[MGA_MAX_WARP_PIPES];
+ unsigned int mAccess;
+} drm_mga_init_t;
+
+/* Warning: if you change the sarea structure, you must change the Xserver
+ * structures as well */
+
+typedef struct _drm_mga_tex_region {
+ unsigned char next, prev;
+ unsigned char in_use;
+ unsigned int age;
+} drm_mga_tex_region_t;
+
+typedef struct _drm_mga_sarea {
+ /* The channel for communication of state information to the kernel
+ * on firing a vertex dma buffer.
+ */
+ unsigned int ContextState[MGA_CTX_SETUP_SIZE];
+ unsigned int ServerState[MGA_2D_SETUP_SIZE];
+ unsigned int TexState[2][MGA_TEX_SETUP_SIZE];
+ unsigned int WarpPipe;
+ unsigned int dirty;
+
+ unsigned int nbox;
+ drm_clip_rect_t boxes[MGA_NR_SAREA_CLIPRECTS];
+
+
+ /* Information about the most recently used 3d drawable. The
+ * client fills in the req_* fields, the server fills in the
+ * exported_ fields and puts the cliprects into boxes, above.
+ *
+ * The client clears the exported_drawable field before
+ * clobbering the boxes data.
+ */
+ unsigned int req_drawable; /* the X drawable id */
+ unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */
+
+ unsigned int exported_drawable;
+ unsigned int exported_index;
+ unsigned int exported_stamp;
+ unsigned int exported_buffers;
+ unsigned int exported_nfront;
+ unsigned int exported_nback;
+ int exported_back_x, exported_front_x, exported_w;
+ int exported_back_y, exported_front_y, exported_h;
+ drm_clip_rect_t exported_boxes[MGA_NR_SAREA_CLIPRECTS];
+
+ /* Counters for aging textures and for client-side throttling.
+ */
+ unsigned int last_enqueue; /* last time a buffer was enqueued */
+ unsigned int last_dispatch; /* age of the most recently dispatched buffer */
+ unsigned int last_quiescent; /* */
+
+
+ /* LRU lists for texture memory in agp space and on the card
+ */
+ drm_mga_tex_region_t texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1];
+ unsigned int texAge[MGA_NR_TEX_HEAPS];
+
+ /* Mechanism to validate card state.
+ */
+ int ctxOwner;
+} drm_mga_sarea_t;
+
+/* Device specific ioctls:
+ */
+typedef struct _drm_mga_clear {
+ unsigned int clear_color;
+ unsigned int clear_depth;
+ unsigned int flags;
+} drm_mga_clear_t;
+
+typedef struct _drm_mga_swap {
+ int dummy;
+} drm_mga_swap_t;
+
+typedef struct _drm_mga_iload {
+ int idx;
+ int length;
+ unsigned int destOrg;
+} drm_mga_iload_t;
+
+typedef struct _drm_mga_vertex {
+ int idx; /* buffer to queue */
+ int used; /* bytes in use */
+ int discard; /* client finished with buffer? */
+} drm_mga_vertex_t;
+
+typedef struct _drm_mga_indices {
+ int idx; /* buffer to queue */
+ unsigned int start;
+ unsigned int end;
+ int discard; /* client finished with buffer? */
+} drm_mga_indices_t;
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/r128_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/r128_drm.h
new file mode 100644
index 000000000..0379a5fae
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/r128_drm.h
@@ -0,0 +1,111 @@
+/* r128_drm.h -- Public header for the r128 driver
+ * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com
+ *
+ * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $XFree86$
+ */
+
+#ifndef _R128_DRM_H_
+#define _R128_DRM_H_
+
+/* WARNING: If you change any of these defines, make sure to change the
+ * defines in the Xserver file (xf86drmR128.h)
+ */
+typedef struct drm_r128_init {
+ enum {
+ R128_INIT_CCE = 0x01,
+ R128_CLEANUP_CCE = 0x02
+ } func;
+ int sarea_priv_offset;
+ int is_pci;
+ int cce_mode;
+ int cce_fifo_size;
+ int cce_secure;
+ int ring_size;
+ int usec_timeout;
+
+ int fb_offset;
+ int agp_ring_offset;
+ int agp_read_ptr_offset;
+ int agp_vertbufs_offset;
+ int agp_indbufs_offset;
+ int agp_textures_offset;
+ int mmio_offset;
+} drm_r128_init_t;
+
+typedef struct drm_r128_packet {
+ unsigned long *buffer;
+ int count;
+ int flags;
+} drm_r128_packet_t;
+
+typedef enum drm_r128_prim {
+ _DRM_R128_PRIM_NONE = 0x0001,
+ _DRM_R128_PRIM_POINT = 0x0002,
+ _DRM_R128_PRIM_LINE = 0x0004,
+ _DRM_R128_PRIM_POLY_LINE = 0x0008,
+ _DRM_R128_PRIM_TRI_LIST = 0x0010,
+ _DRM_R128_PRIM_TRI_FAN = 0x0020,
+ _DRM_R128_PRIM_TRI_STRIP = 0x0040,
+ _DRM_R128_PRIM_TRI_TYPE2 = 0x0080
+} drm_r128_prim_t;
+
+typedef struct drm_r128_vertex {
+ /* Indices here refer to the offset into
+ buflist in drm_buf_get_t. */
+ int send_count; /* Number of buffers to send */
+ int *send_indices; /* List of handles to buffers */
+ int *send_sizes; /* Lengths of data to send */
+ drm_r128_prim_t prim; /* Primitive type */
+ int request_count; /* Number of buffers requested */
+ int *request_indices; /* Buffer information */
+ int *request_sizes;
+ int granted_count; /* Number of buffers granted */
+} drm_r128_vertex_t;
+
+/* WARNING: If you change any of these defines, make sure to change the
+ * defines in the Xserver file (r128_sarea.h)
+ */
+#define R128_LOCAL_TEX_HEAP 0
+#define R128_AGP_TEX_HEAP 1
+#define R128_NR_TEX_HEAPS 2
+#define R128_NR_TEX_REGIONS 64
+#define R128_LOG_TEX_GRANULARITY 16
+
+typedef struct drm_tex_region {
+ unsigned char next, prev;
+ unsigned char in_use;
+ int age;
+} drm_tex_region_t;
+
+typedef struct drm_r128_sarea {
+ drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1];
+ int tex_age[R128_NR_TEX_HEAPS];
+ int ctx_owner;
+ int ring_write;
+} drm_r128_sarea_t;
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/tdfx/Makefile b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/tdfx/Makefile
new file mode 100644
index 000000000..e0ff8ffa4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/tdfx/Makefile
@@ -0,0 +1,15 @@
+# $FreeBSD$
+
+KMOD = tdfx
+SRCS = tdfx_drv.c tdfx_context.c
+SRCS += device_if.h bus_if.h pci_if.h
+CFLAGS += ${DEBUG_FLAGS} -I..
+KERN = /usr/src/sys
+
+@:
+ ln -sf /sys @
+
+machine:
+ ln -sf /sys/i386/include machine
+
+.include "/usr/src/sys/conf/kmod.mk"
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/tdfx/tdfx_context.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/tdfx/tdfx_context.c
new file mode 100644
index 000000000..0aecf762a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/tdfx/tdfx_context.c
@@ -0,0 +1,201 @@
+/* tdfx_context.c -- IOCTLs for tdfx contexts -*- c -*-
+ * Created: Thu Oct 7 10:50:22 1999 by faith@precisioninsight.com
+ * Revised: Sat Oct 9 23:39:56 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI$
+ * $XFree86$
+ *
+ */
+
+#include "drmP.h"
+#include "tdfx_drv.h"
+
+extern drm_ctx_t tdfx_res_ctx;
+
+static int tdfx_alloc_queue(drm_device_t *dev)
+{
+ static int context = 0;
+
+ return ++context; /* Should this reuse contexts in the future? */
+}
+
+int tdfx_context_switch(drm_device_t *dev, int old, int new)
+{
+ char buf[64];
+
+ atomic_inc(&dev->total_ctx);
+
+ if (test_and_set_bit(0, &dev->context_flag)) {
+ DRM_ERROR("Reentering -- FIXME\n");
+ return -EBUSY;
+ }
+
+#if DRM_DMA_HISTOGRAM
+ getnanotime(&dev->ctx_start);
+#endif
+
+ DRM_DEBUG("Context switch from %d to %d\n", old, new);
+
+ if (new == dev->last_context) {
+ clear_bit(0, &dev->context_flag);
+ return 0;
+ }
+
+ if (drm_flags & DRM_FLAG_NOCTX) {
+ tdfx_context_switch_complete(dev, new);
+ } else {
+ sprintf(buf, "C %d %d\n", old, new);
+ drm_write_string(dev, buf);
+ }
+
+ return 0;
+}
+
+int tdfx_context_switch_complete(drm_device_t *dev, int new)
+{
+ dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
+ dev->last_switch = ticks;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("Lock isn't held after context switch\n");
+ }
+
+ /* If a context switch is ever initiated
+ when the kernel holds the lock, release
+ that lock here. */
+#if DRM_DMA_HISTOGRAM
+ {
+ struct timespec ts;
+ getnanotime(&ts);
+ timespecsub(&ts, &dev->lck_start);
+ atomic_inc(&dev->histo.ctx[drm_histogram_slot(&ts)]);
+ }
+#endif
+ clear_bit(0, &dev->context_flag);
+ wakeup(&dev->context_wait);
+
+ return 0;
+}
+
+
+int
+tdfx_resctx(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_ctx_res_t res;
+ drm_ctx_t ctx;
+ int i, error;
+
+ DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
+ res = *(drm_ctx_res_t *) data;
+ if (res.count >= DRM_RESERVED_CONTEXTS) {
+ memset(&ctx, 0, sizeof(ctx));
+ for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
+ ctx.handle = i;
+ error = copyout(&i, &res.contexts[i], sizeof(i));
+ if (error) return error;
+ }
+ }
+ res.count = DRM_RESERVED_CONTEXTS;
+ *(drm_ctx_res_t *) data = res;
+ return 0;
+}
+
+
+int
+tdfx_addctx(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_ctx_t ctx;
+
+ ctx = *(drm_ctx_t *) data;
+ if ((ctx.handle = tdfx_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
+ /* Skip kernel's context and get a new one. */
+ ctx.handle = tdfx_alloc_queue(dev);
+ }
+ DRM_DEBUG("%d\n", ctx.handle);
+ *(drm_ctx_t *) data = ctx;
+ return 0;
+}
+
+int
+tdfx_modctx(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_ctx_t ctx;
+
+ ctx = *(drm_ctx_t *) data;
+ if (ctx.flags==_DRM_CONTEXT_PRESERVED)
+ tdfx_res_ctx.handle=ctx.handle;
+ return 0;
+}
+
+int
+tdfx_getctx(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_ctx_t ctx;
+
+ ctx = *(drm_ctx_t *) data;
+ /* This is 0, because we don't hanlde any context flags */
+ ctx.flags = 0;
+ *(drm_ctx_t *) data = ctx;
+ return 0;
+}
+
+int
+tdfx_switchctx(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_ctx_t ctx;
+
+ ctx = *(drm_ctx_t *) data;
+ DRM_DEBUG("%d\n", ctx.handle);
+ return tdfx_context_switch(dev, dev->last_context, ctx.handle);
+}
+
+int
+tdfx_newctx(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_ctx_t ctx;
+
+ ctx = *(drm_ctx_t *) data;
+ DRM_DEBUG("%d\n", ctx.handle);
+ tdfx_context_switch_complete(dev, ctx.handle);
+
+ return 0;
+}
+
+int
+tdfx_rmctx(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_ctx_t ctx;
+
+ ctx = *(drm_ctx_t *) data;
+ DRM_DEBUG("%d\n", ctx.handle);
+ /* This is currently a noop because we
+ don't reuse context values. Perhaps we
+ should? */
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/tdfx/tdfx_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/tdfx/tdfx_drv.c
new file mode 100644
index 000000000..573cfcf14
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/tdfx/tdfx_drv.c
@@ -0,0 +1,694 @@
+/* tdfx.c -- tdfx driver -*- c -*-
+ * Created: Thu Oct 7 10:38:32 1999 by faith@precisioninsight.com
+ * Revised: Tue Oct 12 08:51:35 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI$
+ * $XFree86$
+ *
+ */
+
+#include "drmP.h"
+#include "tdfx_drv.h"
+
+#include <pci/pcivar.h>
+
+MODULE_DEPEND(tdfx, drm, 1, 1, 1);
+
+#define TDFX_NAME "tdfx"
+#define TDFX_DESC "tdfx"
+#define TDFX_DATE "19991009"
+#define TDFX_MAJOR 0
+#define TDFX_MINOR 0
+#define TDFX_PATCHLEVEL 1
+
+static int tdfx_init(device_t nbdev);
+static void tdfx_cleanup(device_t nbdev);
+
+drm_ctx_t tdfx_res_ctx;
+
+static int tdfx_probe(device_t dev)
+{
+ const char *s = 0;
+
+ switch (pci_get_devid(dev)) {
+ case 0x0003121a:
+ s = "3Dfx Voodoo Banshee graphics accelerator";
+ break;
+
+ case 0x0005121a:
+ s = "3Dfx Voodoo 3 graphics accelerator";
+ break;
+ }
+
+ if (s) {
+ device_set_desc(dev, s);
+ return 0;
+ }
+
+ return ENXIO;
+}
+
+static int tdfx_attach(device_t dev)
+{
+ tdfx_init(dev);
+ return 0;
+}
+
+static int tdfx_detach(device_t dev)
+{
+ tdfx_cleanup(dev);
+ return 0;
+}
+
+static device_method_t tdfx_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, tdfx_probe),
+ DEVMETHOD(device_attach, tdfx_attach),
+ DEVMETHOD(device_detach, tdfx_detach),
+
+ { 0, 0 }
+};
+
+static driver_t tdfx_driver = {
+ "drm",
+ tdfx_methods,
+ sizeof(drm_device_t),
+};
+
+static devclass_t tdfx_devclass;
+#define TDFX_SOFTC(unit) \
+ ((drm_device_t *) devclass_get_softc(tdfx_devclass, unit))
+
+DRIVER_MODULE(if_tdfx, pci, tdfx_driver, tdfx_devclass, 0, 0);
+
+#define CDEV_MAJOR 145
+ /* tdfx_drv.c */
+static d_open_t tdfx_open;
+static d_close_t tdfx_close;
+static d_ioctl_t tdfx_version;
+static d_ioctl_t tdfx_ioctl;
+static d_ioctl_t tdfx_lock;
+static d_ioctl_t tdfx_unlock;
+
+static struct cdevsw tdfx_cdevsw = {
+ /* open */ tdfx_open,
+ /* close */ tdfx_close,
+ /* read */ drm_read,
+ /* write */ drm_write,
+ /* ioctl */ tdfx_ioctl,
+ /* poll */ drm_poll,
+ /* mmap */ drm_mmap,
+ /* strategy */ nostrategy,
+ /* name */ "tdfx",
+ /* maj */ CDEV_MAJOR,
+ /* dump */ nodump,
+ /* psize */ nopsize,
+ /* flags */ D_TTY | D_TRACKCLOSE,
+ /* bmaj */ -1
+};
+
+static drm_ioctl_desc_t tdfx_ioctls[] = {
+ [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { tdfx_version, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_busid, 0, 1 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_block, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { tdfx_addctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { tdfx_rmctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { tdfx_modctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { tdfx_getctx, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { tdfx_switchctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { tdfx_newctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { tdfx_resctx, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { tdfx_lock, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { tdfx_unlock, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 },
+};
+#define TDFX_IOCTL_COUNT DRM_ARRAY_SIZE(tdfx_ioctls)
+
+static int
+tdfx_setup(drm_device_t *dev)
+{
+ int i;
+
+ device_busy(dev->device);
+
+ atomic_set(&dev->ioctl_count, 0);
+ atomic_set(&dev->vma_count, 0);
+ dev->buf_use = 0;
+ atomic_set(&dev->buf_alloc, 0);
+
+ atomic_set(&dev->total_open, 0);
+ atomic_set(&dev->total_close, 0);
+ atomic_set(&dev->total_ioctl, 0);
+ atomic_set(&dev->total_irq, 0);
+ atomic_set(&dev->total_ctx, 0);
+ atomic_set(&dev->total_locks, 0);
+ atomic_set(&dev->total_unlocks, 0);
+ atomic_set(&dev->total_contends, 0);
+ atomic_set(&dev->total_sleeps, 0);
+
+ for (i = 0; i < DRM_HASH_SIZE; i++) {
+ dev->magiclist[i].head = NULL;
+ dev->magiclist[i].tail = NULL;
+ }
+ dev->maplist = NULL;
+ dev->map_count = 0;
+ dev->vmalist = NULL;
+ dev->lock.hw_lock = NULL;
+ dev->lock.lock_queue = 0;
+ dev->queue_count = 0;
+ dev->queue_reserved = 0;
+ dev->queue_slots = 0;
+ dev->queuelist = NULL;
+ dev->irq = 0;
+ dev->context_flag = 0;
+ dev->interrupt_flag = 0;
+ dev->dma = 0;
+ dev->dma_flag = 0;
+ dev->last_context = 0;
+ dev->last_switch = 0;
+ dev->last_checked = 0;
+ callout_init(&dev->timer);
+ dev->context_wait = 0;
+
+ timespecclear(&dev->ctx_start);
+ timespecclear(&dev->lck_start);
+
+ dev->buf_rp = dev->buf;
+ dev->buf_wp = dev->buf;
+ dev->buf_end = dev->buf + DRM_BSZ;
+ bzero(&dev->buf_sel, sizeof dev->buf_sel);
+ dev->buf_sigio = NULL;
+ dev->buf_readers = 0;
+ dev->buf_writers = 0;
+ dev->buf_selecting = 0;
+
+ tdfx_res_ctx.handle=-1;
+
+ DRM_DEBUG("\n");
+
+ /* The kernel's context could be created here, but is now created
+ in drm_dma_enqueue. This is more resource-efficient for
+ hardware that does not do DMA, but may mean that
+ drm_select_queue fails between the time the interrupt is
+ initialized and the time the queues are initialized. */
+
+ return 0;
+}
+
+
+static int
+tdfx_takedown(drm_device_t *dev)
+{
+ int i;
+ drm_magic_entry_t *pt, *next;
+ drm_map_t *map;
+ drm_vma_entry_t *vma, *vma_next;
+
+ DRM_DEBUG("\n");
+
+ lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, curproc);
+ callout_stop(&dev->timer);
+
+ if (dev->devname) {
+ drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
+ dev->devname = NULL;
+ }
+
+ if (dev->unique) {
+ drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
+ dev->unique = NULL;
+ dev->unique_len = 0;
+ }
+ /* Clear pid list */
+ for (i = 0; i < DRM_HASH_SIZE; i++) {
+ for (pt = dev->magiclist[i].head; pt; pt = next) {
+ next = pt->next;
+ drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
+ }
+ dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
+ }
+
+ /* Clear vma list (only built for debugging) */
+ if (dev->vmalist) {
+ for (vma = dev->vmalist; vma; vma = vma_next) {
+ vma_next = vma->next;
+ drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
+ }
+ dev->vmalist = NULL;
+ }
+
+ /* Clear map area and mtrr information */
+ if (dev->maplist) {
+ for (i = 0; i < dev->map_count; i++) {
+ map = dev->maplist[i];
+ switch (map->type) {
+ case _DRM_REGISTERS:
+ case _DRM_FRAME_BUFFER:
+#ifdef CONFIG_MTRR
+ if (map->mtrr >= 0) {
+ int retcode;
+ retcode = mtrr_del(map->mtrr,
+ map->offset,
+ map->size);
+ DRM_DEBUG("mtrr_del = %d\n", retcode);
+ }
+#endif
+ drm_ioremapfree(map->handle, map->size);
+ break;
+ case _DRM_SHM:
+ drm_free_pages((unsigned long)map->handle,
+ drm_order(map->size)
+ - PAGE_SHIFT,
+ DRM_MEM_SAREA);
+ break;
+ case _DRM_AGP:
+ break; /* XXX */
+ }
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ }
+ drm_free(dev->maplist,
+ dev->map_count * sizeof(*dev->maplist),
+ DRM_MEM_MAPS);
+ dev->maplist = NULL;
+ dev->map_count = 0;
+ }
+
+ if (dev->lock.hw_lock) {
+ dev->lock.hw_lock = NULL; /* SHM removed */
+ dev->lock.pid = 0;
+ wakeup(&dev->lock.lock_queue);
+ }
+ lockmgr(&dev->dev_lock, LK_RELEASE, 0, curproc);
+
+ device_unbusy(dev->device);
+
+ return 0;
+}
+
+/* tdfx_init is called via tdfx_attach at module load time, */
+
+static int
+tdfx_init(device_t nbdev)
+{
+ drm_device_t *dev = device_get_softc(nbdev);
+
+ DRM_DEBUG("\n");
+
+ memset((void *)dev, 0, sizeof(*dev));
+ simple_lock_init(&dev->count_lock);
+ lockinit(&dev->dev_lock, PZERO, "drmlk", 0, 0);
+
+#if 0
+ drm_parse_options(tdfx);
+#endif
+
+ dev->device = nbdev;
+ dev->devnode = make_dev(&tdfx_cdevsw,
+ device_get_unit(nbdev),
+ DRM_DEV_UID,
+ DRM_DEV_GID,
+ DRM_DEV_MODE,
+ TDFX_NAME);
+ dev->name = TDFX_NAME;
+
+ drm_mem_init();
+ drm_sysctl_init(dev);
+ TAILQ_INIT(&dev->files);
+
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+ TDFX_NAME,
+ TDFX_MAJOR,
+ TDFX_MINOR,
+ TDFX_PATCHLEVEL,
+ TDFX_DATE,
+ device_get_unit(nbdev));
+
+ return 0;
+}
+
+/* tdfx_cleanup is called via tdfx_detach at module unload time. */
+
+static void
+tdfx_cleanup(device_t nbdev)
+{
+ drm_device_t *dev = device_get_softc(nbdev);
+
+ DRM_DEBUG("\n");
+
+ drm_sysctl_cleanup(dev);
+ destroy_dev(dev->devnode);
+
+ DRM_INFO("Module unloaded\n");
+
+ device_busy(dev->device);
+ tdfx_takedown(dev);
+}
+
+static int
+tdfx_version(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_version_t version;
+ int len;
+
+ version = *(drm_version_t *) data;
+
+#define DRM_COPY(name,value) \
+ len = strlen(value); \
+ if (len > name##_len) len = name##_len; \
+ name##_len = strlen(value); \
+ if (len && name) { \
+ int error = copyout(value, name, len); \
+ if (error) return error; \
+ }
+
+ version.version_major = TDFX_MAJOR;
+ version.version_minor = TDFX_MINOR;
+ version.version_patchlevel = TDFX_PATCHLEVEL;
+
+ DRM_COPY(version.name, TDFX_NAME);
+ DRM_COPY(version.date, TDFX_DATE);
+ DRM_COPY(version.desc, TDFX_DESC);
+
+ *(drm_version_t *) data = version;
+ return 0;
+}
+
+static int
+tdfx_open(dev_t kdev, int flags, int fmt, struct proc *p)
+{
+ drm_device_t *dev = TDFX_SOFTC(minor(kdev));
+ int retcode = 0;
+
+ DRM_DEBUG("open_count = %d\n", dev->open_count);
+
+ device_busy(dev->device);
+ if (!(retcode = drm_open_helper(kdev, flags, fmt, p, dev))) {
+ atomic_inc(&dev->total_open);
+ simple_lock(&dev->count_lock);
+ if (!dev->open_count++) {
+ simple_unlock(&dev->count_lock);
+ retcode = tdfx_setup(dev);
+ }
+ simple_unlock(&dev->count_lock);
+ }
+ device_unbusy(dev->device);
+
+ return retcode;
+}
+
+static int
+tdfx_close(dev_t kdev, int flags, int fmt, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ int retcode = 0;
+
+ DRM_DEBUG("open_count = %d\n", dev->open_count);
+ if (!(retcode = drm_close(kdev, flags, fmt, p))) {
+ atomic_inc(&dev->total_close);
+ simple_lock(&dev->count_lock);
+ if (!--dev->open_count) {
+ if (atomic_read(&dev->ioctl_count) || dev->blocked) {
+ DRM_ERROR("Device busy: %d %d\n",
+ atomic_read(&dev->ioctl_count),
+ dev->blocked);
+ simple_unlock(&dev->count_lock);
+ return EBUSY;
+ }
+ simple_unlock(&dev->count_lock);
+ return tdfx_takedown(dev);
+ }
+ simple_unlock(&dev->count_lock);
+ }
+
+ return retcode;
+}
+
+/* tdfx_ioctl is called whenever a process performs an ioctl on /dev/drm. */
+
+static int
+tdfx_ioctl(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ int nr = DRM_IOCTL_NR(cmd);
+ drm_device_t *dev = kdev->si_drv1;
+ drm_file_t *priv;
+ int retcode = 0;
+ drm_ioctl_desc_t *ioctl;
+ d_ioctl_t *func;
+
+ DRM_DEBUG("dev=%p\n", dev);
+ priv = drm_find_file_by_proc(dev, p);
+ if (!priv) {
+ DRM_DEBUG("can't find authenticator\n");
+ return EINVAL;
+ }
+
+ atomic_inc(&dev->ioctl_count);
+ atomic_inc(&dev->total_ioctl);
+ ++priv->ioctl_count;
+
+ DRM_DEBUG("pid = %d, cmd = 0x%02lx, nr = 0x%02x, auth = %d\n",
+ p->p_pid, cmd, nr, priv->authenticated);
+
+ switch (cmd) {
+ case FIONBIO:
+ atomic_dec(&dev->ioctl_count);
+ return 0;
+
+ case FIOASYNC:
+ atomic_dec(&dev->ioctl_count);
+ dev->flags |= FASYNC;
+ return 0;
+
+ case FIOSETOWN:
+ atomic_dec(&dev->ioctl_count);
+ return fsetown(*(int *)data, &dev->buf_sigio);
+
+ case FIOGETOWN:
+ atomic_dec(&dev->ioctl_count);
+ *(int *) data = fgetown(dev->buf_sigio);
+ return 0;
+ }
+
+ if (nr >= TDFX_IOCTL_COUNT) {
+ retcode = EINVAL;
+ } else {
+ ioctl = &tdfx_ioctls[nr];
+ func = ioctl->func;
+
+ if (!func) {
+ DRM_DEBUG("no function\n");
+ retcode = EINVAL;
+ } else if ((ioctl->root_only && suser(p))
+ || (ioctl->auth_needed && !priv->authenticated)) {
+ retcode = EACCES;
+ } else {
+ retcode = (func)(kdev, cmd, data, flags, p);
+ }
+ }
+
+ atomic_dec(&dev->ioctl_count);
+ return retcode;
+}
+
+static int
+tdfx_lock(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ int ret = 0;
+ drm_lock_t lock;
+#if DRM_DMA_HISTOGRAM
+
+ getnanotime(&dev->lck_start);
+#endif
+
+ lock = *(drm_lock_t *) data;
+
+ if (lock.context == DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("Process %d using kernel context %d\n",
+ p->p_pid, lock.context);
+ return EINVAL;
+ }
+
+ DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
+ lock.context, p->p_pid, dev->lock.hw_lock->lock,
+ lock.flags);
+
+#if 0
+ /* dev->queue_count == 0 right now for
+ tdfx. FIXME? */
+ if (lock.context < 0 || lock.context >= dev->queue_count)
+ return EINVAL;
+#endif
+
+ if (!ret) {
+#if 0
+ if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
+ != lock.context) {
+ long j = ticks - dev->lock.lock_time;
+
+ if (lock.context == tdfx_res_ctx.handle &&
+ j >= 0 && j < DRM_LOCK_SLICE) {
+ /* Can't take lock if we just had it and
+ there is contention. */
+ DRM_DEBUG("%d (pid %d) delayed j=%d dev=%d ticks=%d\n",
+ lock.context, p->p_pid, j,
+ dev->lock.lock_time, ticks);
+ ret = tsleep(&never, PZERO|PCATCH, "drmlk1",
+ DRM_LOCK_SLICE - j);
+ if (ret)
+ return ret;
+ DRM_DEBUG("ticks=%d\n", ticks);
+ }
+ }
+#endif
+ for (;;) {
+ if (!dev->lock.hw_lock) {
+ /* Device has been unregistered */
+ ret = EINTR;
+ break;
+ }
+ if (drm_lock_take(&dev->lock.hw_lock->lock,
+ lock.context)) {
+ dev->lock.pid = p->p_pid;
+ dev->lock.lock_time = ticks;
+ atomic_inc(&dev->total_locks);
+ break; /* Got lock */
+ }
+
+ /* Contention */
+ atomic_inc(&dev->total_sleeps);
+ ret = tsleep(&dev->lock.lock_queue,
+ PZERO|PCATCH,
+ "drmlk2",
+ 0);
+ if (ret)
+ break;
+ }
+ }
+
+#if 0
+ if (!ret && dev->last_context != lock.context &&
+ lock.context != tdfx_res_ctx.handle &&
+ dev->last_context != tdfx_res_ctx.handle) {
+ add_wait_queue(&dev->context_wait, &entry);
+ current->state = TASK_INTERRUPTIBLE;
+ /* PRE: dev->last_context != lock.context */
+ tdfx_context_switch(dev, dev->last_context, lock.context);
+ /* POST: we will wait for the context
+ switch and will dispatch on a later call
+ when dev->last_context == lock.context
+ NOTE WE HOLD THE LOCK THROUGHOUT THIS
+ TIME! */
+ current->policy |= SCHED_YIELD;
+ schedule();
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&dev->context_wait, &entry);
+ if (signal_pending(current)) {
+ ret = EINTR;
+ } else if (dev->last_context != lock.context) {
+ DRM_ERROR("Context mismatch: %d %d\n",
+ dev->last_context, lock.context);
+ }
+ }
+#endif
+
+ if (!ret) {
+ if (lock.flags & _DRM_LOCK_READY) {
+ /* Wait for space in DMA/FIFO */
+ }
+ if (lock.flags & _DRM_LOCK_QUIESCENT) {
+ /* Make hardware quiescent */
+#if 0
+ tdfx_quiescent(dev);
+#endif
+ }
+ }
+
+#if 0
+ DRM_ERROR("pid = %5d, old counter = %5ld\n",
+ p->p_pid, current->counter);
+#endif
+#if 0
+ while (current->counter > 25)
+ current->counter >>= 1; /* decrease time slice */
+ DRM_ERROR("pid = %5d, new counter = %5ld\n",
+ p->p_pid, current->counter);
+#endif
+ DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
+
+#if DRM_DMA_HISTOGRAM
+ {
+ struct timespec ts;
+ getnanotime(&ts);
+ timespecsub(&ts, &dev->lck_start);
+ atomic_inc(&dev->histo.lhld[drm_histogram_slot(&ts)]);
+ }
+#endif
+
+ return ret;
+}
+
+
+static int
+tdfx_unlock(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ drm_device_t *dev = kdev->si_drv1;
+ drm_lock_t lock;
+
+ lock = *(drm_lock_t *) data;
+
+ if (lock.context == DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("Process %d using kernel context %d\n",
+ p->p_pid, lock.context);
+ return EINVAL;
+ }
+
+ DRM_DEBUG("%d frees lock (%d holds)\n",
+ lock.context,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+ atomic_inc(&dev->total_unlocks);
+ if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
+ atomic_inc(&dev->total_contends);
+ drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
+ /* FIXME: Try to send data to card here */
+ if (!dev->context_flag) {
+ if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ DRM_ERROR("\n");
+ }
+ }
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/tdfx/tdfx_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/tdfx/tdfx_drv.h
new file mode 100644
index 000000000..213f8ef1e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/tdfx/tdfx_drv.h
@@ -0,0 +1,47 @@
+/* tdfx_drv.h -- Private header for tdfx driver -*- c -*-
+ * Created: Thu Oct 7 10:40:04 1999 by faith@precisioninsight.com
+ * Revised: Sat Oct 9 23:38:19 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI$
+ * $XFree86$
+ *
+ */
+
+#ifndef _TDFX_DRV_H_
+#define _TDFX_DRV_H_
+
+ /* tdfx_context.c */
+
+extern d_ioctl_t tdfx_resctx;
+extern d_ioctl_t tdfx_addctx;
+extern d_ioctl_t tdfx_modctx;
+extern d_ioctl_t tdfx_getctx;
+extern d_ioctl_t tdfx_switchctx;
+extern d_ioctl_t tdfx_newctx;
+extern d_ioctl_t tdfx_rmctx;
+
+extern int tdfx_context_switch(drm_device_t *dev, int old, int new);
+extern int tdfx_context_switch_complete(drm_device_t *dev, int new);
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drm.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drm.c
new file mode 100644
index 000000000..985c48f9d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drm.c
@@ -0,0 +1,1108 @@
+/* xf86drm.c -- User-level interface to DRM device
+ * Created: Tue Jan 5 08:16:21 1999 by faith@precisioninsight.com
+ * Revised: Wed Aug 4 07:54:23 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.43 1999/08/04 18:14:43 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.4 1999/09/25 14:37:49 dawes Exp $
+ *
+ */
+
+#ifdef XFree86Server
+# include "xf86.h"
+# include "xf86_OSproc.h"
+# include "xf86_ansic.h"
+# include "xf86Priv.h"
+# define _DRM_MALLOC xalloc
+# define _DRM_FREE xfree
+# ifndef XFree86LOADER
+# include <sys/stat.h>
+# include <sys/mman.h>
+# endif
+#else
+# include <stdio.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <ctype.h>
+# include <fcntl.h>
+# include <errno.h>
+# include <signal.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/ioctl.h>
+# include <sys/mman.h>
+# include <sys/time.h>
+# include <sys/types.h>
+# ifdef DRM_USE_MALLOC
+# define _DRM_MALLOC malloc
+# define _DRM_FREE free
+extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void*), void*);
+extern int xf86RemoveSIGIOHandler(int fd);
+# else
+# include <Xlibint.h>
+# define _DRM_MALLOC Xmalloc
+# define _DRM_FREE Xfree
+# endif
+#endif
+
+int sysctlbyname(const char *, void *, size_t *, void *, size_t);
+
+/* Not all systems have MAP_FAILED defined */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#include "xf86drm.h"
+#include "drm.h"
+
+#define makedev(x,y) ((dev_t)(((x) << 8) | (y))) /* create dev_t */
+
+static int drmOpenByBusid(const char *busid);
+static int drmOpenDevice(const char *path, long dev,
+ mode_t mode, uid_t user, gid_t group);
+
+static void *drmHashTable = NULL; /* Context switch callbacks */
+
+typedef struct drmHashEntry {
+ int fd;
+ void (*f)(int, void *, void *);
+ void *tagTable;
+} drmHashEntry;
+
+void *drmMalloc(int size)
+{
+ void *pt;
+ if ((pt = _DRM_MALLOC(size))) memset(pt, 0, size);
+ return pt;
+}
+
+void drmFree(void *pt)
+{
+ if (pt) _DRM_FREE(pt);
+}
+
+static char *drmStrdup(const char *s)
+{
+ return s ? strdup(s) : NULL;
+}
+
+
+static unsigned long drmGetKeyFromFd(int fd)
+{
+#ifdef XFree86LOADER
+ struct xf86stat st;
+#else
+ struct stat st;
+#endif
+
+ st.st_rdev = 0;
+ fstat(fd, &st);
+ return st.st_rdev;
+}
+
+static drmHashEntry *drmGetEntry(int fd)
+{
+ unsigned long key = drmGetKeyFromFd(fd);
+ void *value;
+ drmHashEntry *entry;
+
+ if (!drmHashTable) drmHashTable = drmHashCreate();
+
+ if (drmHashLookup(drmHashTable, key, &value)) {
+ entry = drmMalloc(sizeof(*entry));
+ entry->fd = fd;
+ entry->f = NULL;
+ entry->tagTable = drmHashCreate();
+ drmHashInsert(drmHashTable, key, entry);
+ } else {
+ entry = value;
+ }
+ return entry;
+}
+
+/* drm_open is used to open the /dev/drm device */
+
+static int drm_open(const char *file)
+{
+ int fd = open(file, O_RDWR, 0);
+
+ if (fd >= 0) return fd;
+ return -errno;
+}
+
+/* drmAvailable looks for a usable device node in /dev/dri. */
+
+int drmAvailable(void)
+{
+ int i, fd;
+ char dev_name[64];
+ mode_t mode = DRM_DEV_MODE;
+ mode_t dirmode;
+ gid_t group = DRM_DEV_GID;
+ uid_t user = DRM_DEV_UID;
+ long dev = 0;
+
+ if (!geteuid()) {
+ dirmode = mode;
+ if (dirmode & S_IRUSR) dirmode |= S_IXUSR;
+ if (dirmode & S_IRGRP) dirmode |= S_IXGRP;
+ if (dirmode & S_IROTH) dirmode |= S_IXOTH;
+ dirmode &= ~(S_IWGRP | S_IWOTH);
+ mkdir("/dev/dri", 0);
+ chown("/dev/dri", user, group);
+ chmod("/dev/dri", dirmode);
+ }
+
+ for (i = 0; i < 8; i++) {
+ sprintf(dev_name, "/dev/dri/card%d", i);
+ dev = makedev(145, i);
+ fd = drmOpenDevice(dev_name, dev, mode, user, group);
+ if (fd < 0) {
+ remove(dev_name);
+ continue;
+ }
+ close(fd);
+ return 1;
+ }
+ return 0;
+}
+
+static int drmOpenDevice(const char *path, long dev,
+ mode_t mode, uid_t user, gid_t group)
+{
+#ifdef XFree86LOADER
+ struct xf86stat st;
+#else
+ struct stat st;
+#endif
+
+ if (!stat(path, &st) && st.st_rdev == dev) return drm_open(path);
+
+ if (geteuid()) return DRM_ERR_NOT_ROOT;
+ remove(path);
+ if (mknod(path, S_IFCHR, dev)) {
+ remove(path);
+ return DRM_ERR_NOT_ROOT;
+ }
+ chown(path, user, group);
+ chmod(path, mode);
+ return drm_open(path);
+}
+
+static int drmOpenByName(const char *name)
+{
+ int i;
+ char dev_name[64];
+ mode_t mode = DRM_DEV_MODE;
+ mode_t dirmode;
+ gid_t group = DRM_DEV_GID;
+ uid_t user = DRM_DEV_UID;
+ long dev = 0;
+ drmVersionPtr version;
+ int fd;
+
+#if defined(XFree86Server)
+ mode = xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE;
+ group = xf86ConfigDRI.group ? xf86ConfigDRI.group : DRM_DEV_GID;
+#endif
+
+#if defined(XFree86Server)
+ if (!drmAvailable()) {
+ /* try to load the kernel module now */
+ if (!xf86LoadKernelModule(name)) {
+ ErrorF("[drm] failed to load kernel module \"%s\"\n",
+ name);
+ return -1;
+ }
+ }
+#else
+ if (!drmAvailable())
+ return -1;
+#endif
+
+ if (!geteuid()) {
+ dirmode = mode;
+ if (dirmode & S_IRUSR) dirmode |= S_IXUSR;
+ if (dirmode & S_IRGRP) dirmode |= S_IXGRP;
+ if (dirmode & S_IROTH) dirmode |= S_IXOTH;
+ dirmode &= ~(S_IWGRP | S_IWOTH);
+ mkdir("/dev/dri", 0);
+ chown("/dev/dri", user, group);
+ chmod("/dev/dri", dirmode);
+ }
+
+ for (i = 0; i < 8; i++) {
+ sprintf(dev_name, "/dev/dri/card%d", i);
+ dev = makedev(145, i);
+ fd = drmOpenDevice(dev_name, dev, mode, user, group);
+ if (fd < 0) {
+ remove(dev_name);
+ continue;
+ }
+ version = drmGetVersion(fd);
+ if (!version) {
+ continue;
+ }
+ if (!strcmp(version->name, name)) {
+ drmFreeVersion(version);
+ return fd;
+ }
+ drmFreeVersion(version);
+ }
+
+#if 0
+ for (i = 0; i < 8; i++) {
+ sprintf(sysctl_name, "hw.dri.%d.name", i);
+ sprintf(dev_name, "/dev/dri/card%d", i);
+ len = sizeof(buf);
+ if (sysctlbyname(sysctl_name, buf, &len, 0, 0) == 0) {
+ buf[len-1] = '\0';
+ for (driver = pt = buf; *pt && *pt != ' '; ++pt)
+ ;
+ if (*pt) { /* Device is next */
+ *pt = '\0';
+ if (!strcmp(driver, name)) { /* Match */
+ for (devstring = ++pt; *pt && *pt != ' '; ++pt)
+ ;
+ if (*pt) { /* Found busid */
+ return drmOpenByBusid(++pt);
+ } else { /* No busid */
+ dev = strtol(devstring, NULL, 0);
+ return drmOpenDevice(dev_name, dev,
+ mode, user, group);
+ }
+ }
+ }
+ } else remove(dev_name);
+ }
+#endif
+
+ return -1;
+}
+
+static int drmOpenByBusid(const char *busid)
+{
+ int i;
+ char dev_name[64];
+ char *buf;
+ int fd;
+
+ for (i = 0; i < 8; i++) {
+ sprintf(dev_name, "/dev/dri/card%d", i);
+ if ((fd = drm_open(dev_name)) >= 0) {
+ buf = drmGetBusid(fd);
+ if (buf && !strcmp(buf, busid)) {
+ drmFreeBusid(buf);
+ return fd;
+ }
+ if (buf) drmFreeBusid(buf);
+ close(fd);
+ }
+ }
+ return -1;
+}
+
+
+/* drmOpen looks up the specified name and busid, and opens the device
+ found. The entry in /dev/dri is created if necessary (and if root).
+ A file descriptor is returned. On error, the return value is
+ negative. */
+
+int drmOpen(const char *name, const char *busid)
+{
+ if (busid) return drmOpenByBusid(busid);
+ return drmOpenByName(name);
+}
+
+void drmFreeVersion(drmVersionPtr v)
+{
+ if (!v) return;
+ if (v->name) drmFree(v->name);
+ if (v->date) drmFree(v->date);
+ if (v->desc) drmFree(v->desc);
+ drmFree(v);
+}
+
+static void drmFreeKernelVersion(drm_version_t *v)
+{
+ if (!v) return;
+ if (v->name) drmFree(v->name);
+ if (v->date) drmFree(v->date);
+ if (v->desc) drmFree(v->desc);
+ drmFree(v);
+}
+
+static void drmCopyVersion(drmVersionPtr d, drm_version_t *s)
+{
+ d->version_major = s->version_major;
+ d->version_minor = s->version_minor;
+ d->version_patchlevel = s->version_patchlevel;
+ d->name_len = s->name_len;
+ d->name = drmStrdup(s->name);
+ d->date_len = s->date_len;
+ d->date = drmStrdup(s->date);
+ d->desc_len = s->desc_len;
+ d->desc = drmStrdup(s->desc);
+}
+
+/* drmVersion obtains the version information via an ioctl. Similar
+ * information is available via /proc/drm. */
+
+drmVersionPtr drmGetVersion(int fd)
+{
+ drmVersionPtr retval;
+ drm_version_t *version = drmMalloc(sizeof(*version));
+
+ /* First, get the lengths */
+ version->name_len = 0;
+ version->name = NULL;
+ version->date_len = 0;
+ version->date = NULL;
+ version->desc_len = 0;
+ version->desc = NULL;
+
+ if (ioctl(fd, DRM_IOCTL_VERSION, version)) {
+ drmFreeKernelVersion(version);
+ return NULL;
+ }
+
+ /* Now, allocate space and get the data */
+ if (version->name_len)
+ version->name = drmMalloc(version->name_len + 1);
+ if (version->date_len)
+ version->date = drmMalloc(version->date_len + 1);
+ if (version->desc_len)
+ version->desc = drmMalloc(version->desc_len + 1);
+
+ if (ioctl(fd, DRM_IOCTL_VERSION, version)) {
+ drmFreeKernelVersion(version);
+ return NULL;
+ }
+
+ /* The results might not be null-terminated
+ strings, so terminate them. */
+
+ if (version->name_len) version->name[version->name_len] = '\0';
+ if (version->date_len) version->date[version->date_len] = '\0';
+ if (version->desc_len) version->desc[version->desc_len] = '\0';
+
+ /* Now, copy it all back into the
+ client-visible data structure... */
+ retval = drmMalloc(sizeof(*retval));
+ drmCopyVersion(retval, version);
+ drmFreeKernelVersion(version);
+ return retval;
+}
+
+void drmFreeBusid(const char *busid)
+{
+ drmFree((void *)busid);
+}
+
+char *drmGetBusid(int fd)
+{
+ drm_unique_t u;
+
+ u.unique_len = 0;
+ u.unique = NULL;
+
+ if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) return NULL;
+ u.unique = drmMalloc(u.unique_len + 1);
+ if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) return NULL;
+ u.unique[u.unique_len] = '\0';
+ return u.unique;
+}
+
+int drmSetBusid(int fd, const char *busid)
+{
+ drm_unique_t u;
+
+ u.unique = (char *)busid;
+ u.unique_len = strlen(busid);
+
+ if (ioctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) return -errno;
+ return 0;
+}
+
+int drmGetMagic(int fd, drmMagicPtr magic)
+{
+ drm_auth_t auth;
+
+ *magic = 0;
+ if (ioctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) return -errno;
+ *magic = auth.magic;
+ return 0;
+}
+
+int drmAuthMagic(int fd, drmMagic magic)
+{
+ drm_auth_t auth;
+
+ auth.magic = magic;
+ if (ioctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth)) return -errno;
+ return 0;
+}
+
+int drmAddMap(int fd,
+ drmHandle offset,
+ drmSize size,
+ drmMapType type,
+ drmMapFlags flags,
+ drmHandlePtr handle)
+{
+ drm_map_t map;
+
+ map.offset = offset;
+ map.size = size;
+ map.handle = 0;
+ map.type = type;
+ map.flags = flags;
+ if (ioctl(fd, DRM_IOCTL_ADD_MAP, &map)) return -errno;
+ if (handle) *handle = (drmHandle)map.handle;
+ return 0;
+}
+
+int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
+ int agp_offset)
+{
+ drm_buf_desc_t request;
+
+ request.count = count;
+ request.size = size;
+ request.low_mark = 0;
+ request.high_mark = 0;
+ request.flags = flags;
+ request.agp_start = agp_offset;
+
+ if (ioctl(fd, DRM_IOCTL_ADD_BUFS, &request)) return -errno;
+ return request.count;
+}
+
+int drmMarkBufs(int fd, double low, double high)
+{
+ drm_buf_info_t info;
+ int i;
+
+ info.count = 0;
+ info.list = NULL;
+
+ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) return -EINVAL;
+
+ if (!info.count) return -EINVAL;
+
+ if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
+ return -ENOMEM;
+
+ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
+ int retval = -errno;
+ drmFree(info.list);
+ return retval;
+ }
+
+ for (i = 0; i < info.count; i++) {
+ info.list[i].low_mark = low * info.list[i].count;
+ info.list[i].high_mark = high * info.list[i].count;
+ if (ioctl(fd, DRM_IOCTL_MARK_BUFS, &info.list[i])) {
+ int retval = -errno;
+ drmFree(info.list);
+ return retval;
+ }
+ }
+ drmFree(info.list);
+
+ return 0;
+}
+
+int drmFreeBufs(int fd, int count, int *list)
+{
+ drm_buf_free_t request;
+
+ request.count = count;
+ request.list = list;
+ if (ioctl(fd, DRM_IOCTL_FREE_BUFS, &request)) return -errno;
+ return 0;
+}
+
+int drmClose(int fd)
+{
+ unsigned long key = drmGetKeyFromFd(fd);
+ drmHashEntry *entry = drmGetEntry(fd);
+
+ drmHashDestroy(entry->tagTable);
+ entry->fd = 0;
+ entry->f = NULL;
+ entry->tagTable = NULL;
+
+ drmHashDelete(drmHashTable, key);
+ drmFree(entry);
+
+ return close(fd);
+}
+
+int drmMap(int fd,
+ drmHandle handle,
+ drmSize size,
+ drmAddressPtr address)
+{
+ if (fd < 0) return -EINVAL;
+ *address = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle);
+ if (*address == MAP_FAILED) return -errno;
+ return 0;
+}
+
+int drmUnmap(drmAddress address, drmSize size)
+{
+ return munmap(address, size);
+}
+
+drmBufInfoPtr drmGetBufInfo(int fd)
+{
+ drm_buf_info_t info;
+ drmBufInfoPtr retval;
+ int i;
+
+ info.count = 0;
+ info.list = NULL;
+
+ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) return NULL;
+
+ if (info.count) {
+ if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
+ return NULL;
+
+ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
+ drmFree(info.list);
+ return NULL;
+ }
+ /* Now, copy it all back into the
+ client-visible data structure... */
+ retval = drmMalloc(sizeof(*retval));
+ retval->count = info.count;
+ retval->list = drmMalloc(info.count * sizeof(*retval->list));
+ for (i = 0; i < info.count; i++) {
+ retval->list[i].count = info.list[i].count;
+ retval->list[i].size = info.list[i].size;
+ retval->list[i].low_mark = info.list[i].low_mark;
+ retval->list[i].high_mark = info.list[i].high_mark;
+ }
+ drmFree(info.list);
+ return retval;
+ }
+ return NULL;
+}
+
+drmBufMapPtr drmMapBufs(int fd)
+{
+ drm_buf_map_t bufs;
+ drmBufMapPtr retval;
+ int i;
+
+ bufs.count = 0;
+ bufs.list = NULL;
+ if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) return NULL;
+
+ if (bufs.count) {
+ if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list))))
+ return NULL;
+
+ if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) {
+ drmFree(bufs.list);
+ return NULL;
+ }
+ /* Now, copy it all back into the
+ client-visible data structure... */
+ retval = drmMalloc(sizeof(*retval));
+ retval->count = bufs.count;
+ retval->list = drmMalloc(bufs.count * sizeof(*retval->list));
+ for (i = 0; i < bufs.count; i++) {
+ retval->list[i].idx = bufs.list[i].idx;
+ retval->list[i].total = bufs.list[i].total;
+ retval->list[i].used = 0;
+ retval->list[i].address = bufs.list[i].address;
+ }
+ return retval;
+ }
+ return NULL;
+}
+
+int drmUnmapBufs(drmBufMapPtr bufs)
+{
+ int i;
+
+ for (i = 0; i < bufs->count; i++) {
+ munmap(bufs->list[i].address, bufs->list[i].total);
+ }
+ return 0;
+}
+
+int drmDMA(int fd, drmDMAReqPtr request)
+{
+ drm_dma_t dma;
+
+ /* Copy to hidden structure */
+ dma.context = request->context;
+ dma.send_count = request->send_count;
+ dma.send_indices = request->send_list;
+ dma.send_sizes = request->send_sizes;
+ dma.flags = request->flags;
+ dma.request_count = request->request_count;
+ dma.request_size = request->request_size;
+ dma.request_indices = request->request_list;
+ dma.request_sizes = request->request_sizes;
+ if (ioctl(fd, DRM_IOCTL_DMA, &dma)) return -errno;
+ request->granted_count = dma.granted_count;
+
+ return 0;
+}
+
+int drmGetLock(int fd, drmContext context, drmLockFlags flags)
+{
+ drm_lock_t lock;
+
+ lock.context = context;
+ lock.flags = 0;
+ if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY;
+ if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT;
+ if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH;
+ if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL;
+ if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
+ if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
+
+ while (ioctl(fd, DRM_IOCTL_LOCK, &lock))
+ ;
+ return 0;
+}
+
+int drmUnlock(int fd, drmContext context)
+{
+ drm_lock_t lock;
+
+ lock.context = context;
+ lock.flags = 0;
+ return ioctl(fd, DRM_IOCTL_UNLOCK, &lock);
+}
+
+drmContextPtr drmGetReservedContextList(int fd, int *count)
+{
+ drm_ctx_res_t res;
+ drm_ctx_t *list;
+ drmContextPtr retval;
+ int i;
+
+ res.count = 0;
+ res.contexts = NULL;
+ if (ioctl(fd, DRM_IOCTL_RES_CTX, &res)) return NULL;
+
+ if (!res.count) return NULL;
+
+ if (!(list = drmMalloc(res.count * sizeof(*list)))) return NULL;
+ if (!(retval = drmMalloc(res.count * sizeof(*retval)))) {
+ drmFree(list);
+ return NULL;
+ }
+
+ res.contexts = list;
+ if (ioctl(fd, DRM_IOCTL_RES_CTX, &res)) return NULL;
+
+ for (i = 0; i < res.count; i++) retval[i] = list[i].handle;
+ drmFree(list);
+
+ *count = res.count;
+ return retval;
+}
+
+void drmFreeReservedContextList(drmContextPtr pt)
+{
+ drmFree(pt);
+}
+
+int drmCreateContext(int fd, drmContextPtr handle)
+{
+ drm_ctx_t ctx;
+
+ ctx.flags = 0; /* Modified with functions below */
+ if (ioctl(fd, DRM_IOCTL_ADD_CTX, &ctx)) return -errno;
+ *handle = ctx.handle;
+ return 0;
+}
+
+int drmSwitchToContext(int fd, drmContext context)
+{
+ drm_ctx_t ctx;
+
+ ctx.handle = context;
+ if (ioctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx)) return -errno;
+ return 0;
+}
+
+int drmSetContextFlags(int fd, drmContext context, drmContextFlags flags)
+{
+ drm_ctx_t ctx;
+
+ /* Context preserving means that no context
+ switched are done between DMA buffers
+ from one context and the next. This is
+ suitable for use in the X server (which
+ promises to maintain hardware context,
+ or in the client-side library when
+ buffers are swapped on behalf of two
+ threads. */
+ ctx.handle = context;
+ ctx.flags = 0;
+ if (flags & DRM_CONTEXT_PRESERVED) ctx.flags |= _DRM_CONTEXT_PRESERVED;
+ if (flags & DRM_CONTEXT_2DONLY) ctx.flags |= _DRM_CONTEXT_2DONLY;
+ if (ioctl(fd, DRM_IOCTL_MOD_CTX, &ctx)) return -errno;
+ return 0;
+}
+
+int drmGetContextFlags(int fd, drmContext context, drmContextFlagsPtr flags)
+{
+ drm_ctx_t ctx;
+
+ ctx.handle = context;
+ if (ioctl(fd, DRM_IOCTL_GET_CTX, &ctx)) return -errno;
+ *flags = 0;
+ if (ctx.flags & _DRM_CONTEXT_PRESERVED) *flags |= DRM_CONTEXT_PRESERVED;
+ if (ctx.flags & _DRM_CONTEXT_2DONLY) *flags |= DRM_CONTEXT_2DONLY;
+ return 0;
+}
+
+int drmDestroyContext(int fd, drmContext handle)
+{
+ drm_ctx_t ctx;
+ ctx.handle = handle;
+ if (ioctl(fd, DRM_IOCTL_RM_CTX, &ctx)) return -errno;
+ return 0;
+}
+
+int drmCreateDrawable(int fd, drmDrawablePtr handle)
+{
+ drm_draw_t draw;
+ if (ioctl(fd, DRM_IOCTL_ADD_DRAW, &draw)) return -errno;
+ *handle = draw.handle;
+ return 0;
+}
+
+int drmDestroyDrawable(int fd, drmDrawable handle)
+{
+ drm_draw_t draw;
+ draw.handle = handle;
+ if (ioctl(fd, DRM_IOCTL_RM_DRAW, &draw)) return -errno;
+ return 0;
+}
+
+int drmAgpAcquire(int fd)
+{
+ if (ioctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL)) return -errno;
+ return 0;
+}
+
+int drmAgpRelease(int fd)
+{
+ if (ioctl(fd, DRM_IOCTL_AGP_RELEASE, NULL)) return -errno;
+ return 0;
+}
+
+int drmAgpEnable(int fd, unsigned long mode)
+{
+ drm_agp_mode_t m;
+
+ m.mode = mode;
+ if (ioctl(fd, DRM_IOCTL_AGP_ENABLE, &m)) return -errno;
+ return 0;
+}
+
+int drmAgpAlloc(int fd, unsigned long size, unsigned long type,
+ unsigned long *address, unsigned long *handle)
+{
+ drm_agp_buffer_t b;
+ *handle = 0;
+ b.size = size;
+ b.handle = 0;
+ b.type = type;
+ if (ioctl(fd, DRM_IOCTL_AGP_ALLOC, &b)) return -errno;
+ if (address != 0UL) *address = b.physical;
+ *handle = b.handle;
+ return 0;
+}
+
+int drmAgpFree(int fd, unsigned long handle)
+{
+ drm_agp_buffer_t b;
+
+ b.size = 0;
+ b.handle = handle;
+ if (ioctl(fd, DRM_IOCTL_AGP_FREE, &b)) return -errno;
+ return 0;
+}
+
+int drmAgpBind(int fd, unsigned long handle, unsigned long offset)
+{
+ drm_agp_binding_t b;
+
+ b.handle = handle;
+ b.offset = offset;
+ if (ioctl(fd, DRM_IOCTL_AGP_BIND, &b)) return -errno;
+ return 0;
+}
+
+int drmAgpUnbind(int fd, unsigned long handle)
+{
+ drm_agp_binding_t b;
+
+ b.handle = handle;
+ b.offset = 0;
+ if (ioctl(fd, DRM_IOCTL_AGP_UNBIND, &b)) return -errno;
+ return 0;
+}
+
+int drmAgpVersionMajor(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno;
+ return i.agp_version_major;
+}
+
+int drmAgpVersionMinor(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno;
+ return i.agp_version_minor;
+}
+
+unsigned long drmAgpGetMode(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.mode;
+}
+
+unsigned long drmAgpBase(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.aperture_base;
+}
+
+unsigned long drmAgpSize(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.aperture_size;
+}
+
+unsigned long drmAgpMemoryUsed(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.memory_used;
+}
+
+unsigned long drmAgpMemoryAvail(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.memory_allowed;
+}
+
+unsigned int drmAgpVendorId(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.id_vendor;
+}
+
+unsigned int drmAgpDeviceId(int fd)
+{
+ drm_agp_info_t i;
+
+ if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+ return i.id_device;
+}
+
+int drmError(int err, const char *label)
+{
+ switch (err) {
+ case DRM_ERR_NO_DEVICE: fprintf(stderr, "%s: no device\n", label); break;
+ case DRM_ERR_NO_ACCESS: fprintf(stderr, "%s: no access\n", label); break;
+ case DRM_ERR_NOT_ROOT: fprintf(stderr, "%s: not root\n", label); break;
+ case DRM_ERR_INVALID: fprintf(stderr, "%s: invalid args\n", label);break;
+ default:
+ if (err < 0) err = -err;
+ fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) );
+ break;
+ }
+
+ return 1;
+}
+
+int drmCtlInstHandler(int fd, int irq)
+{
+ drm_control_t ctl;
+
+ ctl.func = DRM_INST_HANDLER;
+ ctl.irq = irq;
+ if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno;
+ return 0;
+}
+
+int drmCtlUninstHandler(int fd)
+{
+ drm_control_t ctl;
+
+ ctl.func = DRM_UNINST_HANDLER;
+ ctl.irq = 0;
+ if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno;
+ return 0;
+}
+
+int drmFinish(int fd, int context, drmLockFlags flags)
+{
+ drm_lock_t lock;
+
+ lock.context = context;
+ lock.flags = 0;
+ if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY;
+ if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT;
+ if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH;
+ if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL;
+ if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
+ if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
+ if (ioctl(fd, DRM_IOCTL_FINISH, &lock)) return -errno;
+ return 0;
+}
+
+int drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum)
+{
+ drm_irq_busid_t p;
+
+ p.busnum = busnum;
+ p.devnum = devnum;
+ p.funcnum = funcnum;
+ if (ioctl(fd, DRM_IOCTL_IRQ_BUSID, &p)) return -errno;
+ return p.irq;
+}
+
+int drmAddContextTag(int fd, drmContext context, void *tag)
+{
+ drmHashEntry *entry = drmGetEntry(fd);
+
+ if (drmHashInsert(entry->tagTable, context, tag)) {
+ drmHashDelete(entry->tagTable, context);
+ drmHashInsert(entry->tagTable, context, tag);
+ }
+ return 0;
+}
+
+int drmDelContextTag(int fd, drmContext context)
+{
+ drmHashEntry *entry = drmGetEntry(fd);
+
+ return drmHashDelete(entry->tagTable, context);
+}
+
+void *drmGetContextTag(int fd, drmContext context)
+{
+ drmHashEntry *entry = drmGetEntry(fd);
+ void *value;
+
+ if (drmHashLookup(entry->tagTable, context, &value)) return NULL;
+
+ return value;
+}
+
+#if defined(XFree86Server) || defined(DRM_USE_MALLOC)
+static void drmSIGIOHandler(int interrupt, void *arg)
+{
+ unsigned long key;
+ void *value;
+ ssize_t count;
+ drm_ctx_t ctx;
+ typedef void (*_drmCallback)(int, void *, void *);
+ char buf[256];
+ drmContext old;
+ drmContext new;
+ void *oldctx;
+ void *newctx;
+ char *pt;
+ drmHashEntry *entry;
+
+ if (!drmHashTable) return;
+ if (drmHashFirst(drmHashTable, &key, &value)) {
+ entry = value;
+ do {
+#if 1
+ fprintf(stderr, "Trying %d\n", entry->fd);
+#endif
+ if ((count = read(entry->fd, buf, sizeof(buf)))) {
+ buf[count] = '\0';
+#if 1
+ fprintf(stderr, "Got %s\n", buf);
+#endif
+
+ for (pt = buf; *pt != ' '; ++pt); /* Find first space */
+ ++pt;
+ old = strtol(pt, &pt, 0);
+ new = strtol(pt, NULL, 0);
+ oldctx = drmGetContextTag(entry->fd, old);
+ newctx = drmGetContextTag(entry->fd, new);
+#if 1
+ fprintf(stderr, "%d %d %p %p\n", old, new, oldctx, newctx);
+#endif
+ ((_drmCallback)entry->f)(entry->fd, oldctx, newctx);
+ ctx.handle = new;
+ ioctl(entry->fd, DRM_IOCTL_NEW_CTX, &ctx);
+ }
+ } while (drmHashNext(drmHashTable, &key, &value));
+ }
+}
+
+int drmInstallSIGIOHandler(int fd, void (*f)(int, void *, void *))
+{
+ drmHashEntry *entry;
+
+ entry = drmGetEntry(fd);
+ entry->f = f;
+
+ return xf86InstallSIGIOHandler(fd, drmSIGIOHandler, 0);
+}
+
+int drmRemoveSIGIOHandler(int fd)
+{
+ drmHashEntry *entry = drmGetEntry(fd);
+
+ entry->f = NULL;
+
+ return xf86RemoveSIGIOHandler(fd);
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmHash.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmHash.c
new file mode 100644
index 000000000..a3c9481b5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmHash.c
@@ -0,0 +1,435 @@
+/* xf86drmHash.c -- Small hash table support for integer -> integer mapping
+ * Created: Sun Apr 18 09:35:45 1999 by faith@precisioninsight.com
+ * Revised: Thu Jun 3 16:11:06 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c,v 1.3 1999/06/07 13:01:42 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c,v 1.1 1999/06/14 07:32:02 dawes Exp $
+ *
+ * DESCRIPTION
+ *
+ * This file contains a straightforward implementation of a fixed-sized
+ * hash table using self-organizing linked lists [Knuth73, pp. 398-399] for
+ * collision resolution. There are two potentially interesting things
+ * about this implementation:
+ *
+ * 1) The table is power-of-two sized. Prime sized tables are more
+ * traditional, but do not have a significant advantage over power-of-two
+ * sized table, especially when double hashing is not used for collision
+ * resolution.
+ *
+ * 2) The hash computation uses a table of random integers [Hanson97,
+ * pp. 39-41].
+ *
+ * FUTURE ENHANCEMENTS
+ *
+ * With a table size of 512, the current implementation is sufficient for a
+ * few hundred keys. Since this is well above the expected size of the
+ * tables for which this implementation was designed, the implementation of
+ * dynamic hash tables was postponed until the need arises. A common (and
+ * naive) approach to dynamic hash table implementation simply creates a
+ * new hash table when necessary, rehashes all the data into the new table,
+ * and destroys the old table. The approach in [Larson88] is superior in
+ * two ways: 1) only a portion of the table is expanded when needed,
+ * distributing the expansion cost over several insertions, and 2) portions
+ * of the table can be locked, enabling a scalable thread-safe
+ * implementation.
+ *
+ * REFERENCES
+ *
+ * [Hanson97] David R. Hanson. C Interfaces and Implementations:
+ * Techniques for Creating Reusable Software. Reading, Massachusetts:
+ * Addison-Wesley, 1997.
+ *
+ * [Knuth73] Donald E. Knuth. The Art of Computer Programming. Volume 3:
+ * Sorting and Searching. Reading, Massachusetts: Addison-Wesley, 1973.
+ *
+ * [Larson88] Per-Ake Larson. "Dynamic Hash Tables". CACM 31(4), April
+ * 1988, pp. 446-457.
+ *
+ */
+
+#define HASH_MAIN 0
+
+#if HASH_MAIN
+# include <stdio.h>
+# include <stdlib.h>
+#else
+# include "xf86drm.h"
+# ifdef XFree86LOADER
+# include "xf86.h"
+# include "xf86_ansic.h"
+# else
+# include <stdio.h>
+# include <stdlib.h>
+# endif
+#endif
+
+#define N(x) drm##x
+
+#define HASH_MAGIC 0xdeadbeef
+#define HASH_DEBUG 0
+#define HASH_SIZE 512 /* Good for about 100 entries */
+ /* If you change this value, you probably
+ have to change the HashHash hashing
+ function! */
+
+#if HASH_MAIN
+#define HASH_ALLOC malloc
+#define HASH_FREE free
+#define HASH_RANDOM_DECL
+#define HASH_RANDOM_INIT(seed) srandom(seed)
+#define HASH_RANDOM random()
+#else
+#define HASH_ALLOC drmMalloc
+#define HASH_FREE drmFree
+#define HASH_RANDOM_DECL void *state
+#define HASH_RANDOM_INIT(seed) state = drmRandomCreate(seed)
+#define HASH_RANDOM drmRandom(state)
+
+#endif
+
+typedef struct HashBucket {
+ unsigned long key;
+ void *value;
+ struct HashBucket *next;
+} HashBucket, *HashBucketPtr;
+
+typedef struct HashTable {
+ unsigned long magic;
+ unsigned long entries;
+ unsigned long hits; /* At top of linked list */
+ unsigned long partials; /* Not at top of linked list */
+ unsigned long misses; /* Not in table */
+ HashBucketPtr buckets[HASH_SIZE];
+ int p0;
+ HashBucketPtr p1;
+} HashTable, *HashTablePtr;
+
+#if HASH_MAIN
+extern void *N(HashCreate)(void);
+extern int N(HashDestroy)(void *t);
+extern int N(HashLookup)(void *t, unsigned long key, unsigned long *value);
+extern int N(HashInsert)(void *t, unsigned long key, unsigned long value);
+extern int N(HashDelete)(void *t, unsigned long key);
+#endif
+
+static unsigned long HashHash(unsigned long key)
+{
+ unsigned long hash = 0;
+ unsigned long tmp = key;
+ static int init = 0;
+ static unsigned long scatter[256];
+ int i;
+
+ if (!init) {
+ HASH_RANDOM_DECL;
+ HASH_RANDOM_INIT(37);
+ for (i = 0; i < 256; i++) scatter[i] = HASH_RANDOM;
+ ++init;
+ }
+
+ while (tmp) {
+ hash = (hash << 1) + scatter[tmp & 0xff];
+ tmp >>= 8;
+ }
+
+ hash %= HASH_SIZE;
+#if HASH_DEBUG
+ printf( "Hash(%d) = %d\n", key, hash);
+#endif
+ return hash;
+}
+
+void *N(HashCreate)(void)
+{
+ HashTablePtr table;
+ int i;
+
+ table = HASH_ALLOC(sizeof(*table));
+ if (!table) return NULL;
+ table->magic = HASH_MAGIC;
+ table->entries = 0;
+ table->hits = 0;
+ table->partials = 0;
+ table->misses = 0;
+
+ for (i = 0; i < HASH_SIZE; i++) table->buckets[i] = NULL;
+ return table;
+}
+
+int N(HashDestroy)(void *t)
+{
+ HashTablePtr table = (HashTablePtr)t;
+ HashBucketPtr bucket;
+ HashBucketPtr next;
+ int i;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ for (i = 0; i < HASH_SIZE; i++) {
+ for (bucket = table->buckets[i]; bucket;) {
+ next = bucket->next;
+ HASH_FREE(bucket);
+ bucket = next;
+ }
+ }
+ HASH_FREE(table);
+ return 0;
+}
+
+/* Find the bucket and organize the list so that this bucket is at the
+ top. */
+
+static HashBucketPtr HashFind(HashTablePtr table,
+ unsigned long key, unsigned long *h)
+{
+ unsigned long hash = HashHash(key);
+ HashBucketPtr prev = NULL;
+ HashBucketPtr bucket;
+
+ if (h) *h = hash;
+
+ for (bucket = table->buckets[hash]; bucket; bucket = bucket->next) {
+ if (bucket->key == key) {
+ if (prev) {
+ /* Organize */
+ prev->next = bucket->next;
+ bucket->next = table->buckets[hash];
+ table->buckets[hash] = bucket;
+ ++table->partials;
+ } else {
+ ++table->hits;
+ }
+ return bucket;
+ }
+ prev = bucket;
+ }
+ ++table->misses;
+ return NULL;
+}
+
+int N(HashLookup)(void *t, unsigned long key, void **value)
+{
+ HashTablePtr table = (HashTablePtr)t;
+ HashBucketPtr bucket;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ bucket = HashFind(table, key, NULL);
+ if (!bucket) return 1; /* Not found */
+ *value = bucket->value;
+ return 0; /* Found */
+}
+
+int N(HashInsert)(void *t, unsigned long key, void *value)
+{
+ HashTablePtr table = (HashTablePtr)t;
+ HashBucketPtr bucket;
+ unsigned long hash;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ if (HashFind(table, key, &hash)) return 1; /* Already in table */
+
+ bucket = HASH_ALLOC(sizeof(*bucket));
+ if (!bucket) return -1; /* Error */
+ bucket->key = key;
+ bucket->value = value;
+ bucket->next = table->buckets[hash];
+ table->buckets[hash] = bucket;
+#if HASH_DEBUG
+ printf("Inserted %d at %d/%p\n", key, hash, bucket);
+#endif
+ return 0; /* Added to table */
+}
+
+int N(HashDelete)(void *t, unsigned long key)
+{
+ HashTablePtr table = (HashTablePtr)t;
+ unsigned long hash;
+ HashBucketPtr bucket;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ bucket = HashFind(table, key, &hash);
+
+ if (!bucket) return 1; /* Not found */
+
+ table->buckets[hash] = bucket->next;
+ HASH_FREE(bucket);
+ return 0;
+}
+
+int N(HashNext)(void *t, unsigned long *key, void **value)
+{
+ HashTablePtr table = (HashTablePtr)t;
+
+ for (; table->p0 < HASH_SIZE;
+ ++table->p0, table->p1 = table->buckets[table->p0]) {
+ if (table->p1) {
+ *key = table->p1->key;
+ *value = table->p1->value;
+ table->p1 = table->p1->next;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int N(HashFirst)(void *t, unsigned long *key, void **value)
+{
+ HashTablePtr table = (HashTablePtr)t;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ table->p0 = 0;
+ table->p1 = table->buckets[0];
+ return N(HashNext)(table, key, value);
+}
+
+#if HASH_MAIN
+#define DIST_LIMIT 10
+static int dist[DIST_LIMIT];
+
+static void clear_dist(void) {
+ int i;
+
+ for (i = 0; i < DIST_LIMIT; i++) dist[i] = 0;
+}
+
+static int count_entries(HashBucketPtr bucket)
+{
+ int count = 0;
+
+ for (; bucket; bucket = bucket->next) ++count;
+ return count;
+}
+
+static void update_dist(int count)
+{
+ if (count >= DIST_LIMIT) ++dist[DIST_LIMIT-1];
+ else ++dist[count];
+}
+
+static void compute_dist(HashTablePtr table)
+{
+ int i;
+ HashBucketPtr bucket;
+
+ printf("Entries = %ld, hits = %ld, partials = %ld, misses = %ld\n",
+ table->entries, table->hits, table->partials, table->misses);
+ clear_dist();
+ for (i = 0; i < HASH_SIZE; i++) {
+ bucket = table->buckets[i];
+ update_dist(count_entries(bucket));
+ }
+ for (i = 0; i < DIST_LIMIT; i++) {
+ if (i != DIST_LIMIT-1) printf("%5d %10d\n", i, dist[i]);
+ else printf("other %10d\n", dist[i]);
+ }
+}
+
+static void check_table(HashTablePtr table,
+ unsigned long key, unsigned long value)
+{
+ unsigned long retval = 0;
+ int retcode = N(HashLookup)(table, key, &retval);
+
+ switch (retcode) {
+ case -1:
+ printf("Bad magic = 0x%08lx:"
+ " key = %lu, expected = %lu, returned = %lu\n",
+ table->magic, key, value, retval);
+ break;
+ case 1:
+ printf("Not found: key = %lu, expected = %lu returned = %lu\n",
+ key, value, retval);
+ break;
+ case 0:
+ if (value != retval)
+ printf("Bad value: key = %lu, expected = %lu, returned = %lu\n",
+ key, value, retval);
+ break;
+ default:
+ printf("Bad retcode = %d: key = %lu, expected = %lu, returned = %lu\n",
+ retcode, key, value, retval);
+ break;
+ }
+}
+
+int main(void)
+{
+ HashTablePtr table;
+ int i;
+
+ printf("\n***** 256 consecutive integers ****\n");
+ table = N(HashCreate)();
+ for (i = 0; i < 256; i++) N(HashInsert)(table, i, i);
+ for (i = 0; i < 256; i++) check_table(table, i, i);
+ for (i = 256; i >= 0; i--) check_table(table, i, i);
+ compute_dist(table);
+ N(HashDestroy)(table);
+
+ printf("\n***** 1024 consecutive integers ****\n");
+ table = N(HashCreate)();
+ for (i = 0; i < 1024; i++) N(HashInsert)(table, i, i);
+ for (i = 0; i < 1024; i++) check_table(table, i, i);
+ for (i = 1024; i >= 0; i--) check_table(table, i, i);
+ compute_dist(table);
+ N(HashDestroy)(table);
+
+ printf("\n***** 1024 consecutive page addresses (4k pages) ****\n");
+ table = N(HashCreate)();
+ for (i = 0; i < 1024; i++) N(HashInsert)(table, i*4096, i);
+ for (i = 0; i < 1024; i++) check_table(table, i*4096, i);
+ for (i = 1024; i >= 0; i--) check_table(table, i*4096, i);
+ compute_dist(table);
+ N(HashDestroy)(table);
+
+ printf("\n***** 1024 random integers ****\n");
+ table = N(HashCreate)();
+ srandom(0xbeefbeef);
+ for (i = 0; i < 1024; i++) N(HashInsert)(table, random(), i);
+ srandom(0xbeefbeef);
+ for (i = 0; i < 1024; i++) check_table(table, random(), i);
+ srandom(0xbeefbeef);
+ for (i = 0; i < 1024; i++) check_table(table, random(), i);
+ compute_dist(table);
+ N(HashDestroy)(table);
+
+ printf("\n***** 5000 random integers ****\n");
+ table = N(HashCreate)();
+ srandom(0xbeefbeef);
+ for (i = 0; i < 5000; i++) N(HashInsert)(table, random(), i);
+ srandom(0xbeefbeef);
+ for (i = 0; i < 5000; i++) check_table(table, random(), i);
+ srandom(0xbeefbeef);
+ for (i = 0; i < 5000; i++) check_table(table, random(), i);
+ compute_dist(table);
+ N(HashDestroy)(table);
+
+ return 0;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmI810.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmI810.c
new file mode 100644
index 000000000..067c6376e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmI810.c
@@ -0,0 +1,86 @@
+#ifdef XFree86Server
+# include "xf86.h"
+# include "xf86_OSproc.h"
+# include "xf86_ansic.h"
+# include "xf86Priv.h"
+# define _DRM_MALLOC xalloc
+# define _DRM_FREE xfree
+# ifndef XFree86LOADER
+# include <sys/stat.h>
+# include <sys/mman.h>
+# endif
+#else
+# include <stdio.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <ctype.h>
+# include <fcntl.h>
+# include <errno.h>
+# include <signal.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/ioctl.h>
+# include <sys/mman.h>
+# include <sys/time.h>
+# ifdef DRM_USE_MALLOC
+# define _DRM_MALLOC malloc
+# define _DRM_FREE free
+extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *);
+extern int xf86RemoveSIGIOHandler(int fd);
+# else
+# include <Xlibint.h>
+# define _DRM_MALLOC Xmalloc
+# define _DRM_FREE Xfree
+# endif
+#endif
+
+/* Not all systems have MAP_FAILED defined */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#include "xf86drm.h"
+#include "xf86drmI810.h"
+#include "drm.h"
+
+Bool drmI810CleanupDma(int driSubFD)
+{
+ drm_i810_init_t init;
+
+ memset(&init, 0, sizeof(drm_i810_init_t));
+ init.func = I810_CLEANUP_DMA;
+
+ if(ioctl(driSubFD, DRM_IOCTL_I810_INIT, &init)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool drmI810InitDma(int driSubFD, drmI810Init *info)
+{
+ drm_i810_init_t init;
+
+ memset(&init, 0, sizeof(drm_i810_init_t));
+
+ init.func = I810_INIT_DMA;
+ init.ring_map_idx = info->ring_map_idx;
+ init.buffer_map_idx = info->buffer_map_idx;
+ init.ring_start = info->start;
+ init.ring_end = info->end;
+ init.ring_size = info->size;
+ init.sarea_priv_offset = info->sarea_off;
+ init.front_offset = info->front_offset;
+ init.back_offset = info->back_offset;
+ init.depth_offset = info->depth_offset;
+ init.w = info->w;
+ init.h = info->h;
+ init.pitch = info->pitch;
+ init.pitch_bits = info->pitch_bits;
+
+ if(ioctl(driSubFD, DRM_IOCTL_I810_INIT, &init)) {
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmMga.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmMga.c
new file mode 100644
index 000000000..aa3a6c745
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmMga.c
@@ -0,0 +1,116 @@
+#ifdef XFree86Server
+# include "xf86.h"
+# include "xf86_OSproc.h"
+# include "xf86_ansic.h"
+# include "xf86Priv.h"
+# define _DRM_MALLOC xalloc
+# define _DRM_FREE xfree
+# ifndef XFree86LOADER
+# include <sys/stat.h>
+# include <sys/mman.h>
+# endif
+#else
+# include <stdio.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <ctype.h>
+# include <fcntl.h>
+# include <errno.h>
+# include <signal.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/ioctl.h>
+# include <sys/mman.h>
+# include <sys/time.h>
+# ifdef DRM_USE_MALLOC
+# define _DRM_MALLOC malloc
+# define _DRM_FREE free
+extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *);
+extern int xf86RemoveSIGIOHandler(int fd);
+# else
+# include <Xlibint.h>
+# define _DRM_MALLOC Xmalloc
+# define _DRM_FREE Xfree
+# endif
+#endif
+
+/* Not all systems have MAP_FAILED defined */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#include "xf86drm.h"
+#include "xf86drmMga.h"
+#include "drm.h"
+
+Bool drmMgaCleanupDma(int driSubFD)
+{
+ drm_mga_init_t init;
+ memset(&init, 0, sizeof(drm_mga_init_t));
+ init.func = MGA_CLEANUP_DMA;
+ if(ioctl(driSubFD, DRM_IOCTL_MGA_INIT, &init)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool drmMgaLockUpdate(int driSubFD, drmLockFlags flags)
+{
+ drm_lock_t lock;
+
+ memset(&lock, 0, sizeof(drm_lock_t));
+
+ if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT;
+ if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH;
+ if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL;
+
+ if(ioctl(driSubFD, DRM_IOCTL_MGA_FLUSH, &lock)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool drmMgaInitDma(int driSubFD, drmMgaInit *info)
+{
+ drm_mga_init_t init;
+ int i;
+
+ memset(&init, 0, sizeof(drm_mga_init_t));
+ init.func = MGA_INIT_DMA;
+ init.reserved_map_agpstart = info->reserved_map_agpstart;
+ init.reserved_map_idx = info->reserved_map_idx;
+ init.buffer_map_idx = info->buffer_map_idx;
+ init.sarea_priv_offset = info->sarea_priv_offset;
+ init.primary_size = info->primary_size;
+ init.warp_ucode_size = info->warp_ucode_size;
+ init.frontOffset = info->frontOffset;
+ init.backOffset = info->backOffset;
+ init.depthOffset = info->depthOffset;
+ init.textureOffset = info->textureOffset;
+ init.textureSize = info->textureSize;
+ init.agpTextureSize = info->agpTextureSize;
+ init.agpTextureOffset = info->agpTextureOffset;
+ init.cpp = info->cpp;
+ init.stride = info->stride;
+ init.sgram = info->sgram;
+ init.chipset = info->chipset;
+
+ for(i = 0; i < MGA_MAX_WARP_PIPES; i++) {
+ init.WarpIndex[i].installed = info->WarpIndex[i].installed;
+ init.WarpIndex[i].phys_addr = info->WarpIndex[i].phys_addr;
+ init.WarpIndex[i].size = info->WarpIndex[i].size;
+ }
+
+ init.mAccess = info->mAccess;
+
+
+
+ if(ioctl(driSubFD, DRM_IOCTL_MGA_INIT, &init)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmR128.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmR128.c
new file mode 100644
index 000000000..4195c90ba
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmR128.c
@@ -0,0 +1,198 @@
+/* xf86drmR128.c -- User-level interface to Rage 128 DRM device
+ * Created: Sun Apr 9 18:13:54 2000 by kevin@precisioninsight.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $XFree86$
+ *
+ */
+
+#ifdef XFree86Server
+# include "xf86.h"
+# include "xf86_OSproc.h"
+# include "xf86_ansic.h"
+# include "xf86Priv.h"
+# define _DRM_MALLOC xalloc
+# define _DRM_FREE xfree
+# ifndef XFree86LOADER
+# include <sys/stat.h>
+# include <sys/mman.h>
+# endif
+#else
+# include <stdio.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <ctype.h>
+# include <fcntl.h>
+# include <errno.h>
+# include <signal.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/ioctl.h>
+# include <sys/mman.h>
+# include <sys/time.h>
+# ifdef DRM_USE_MALLOC
+# define _DRM_MALLOC malloc
+# define _DRM_FREE free
+extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *);
+extern int xf86RemoveSIGIOHandler(int fd);
+# else
+# include <Xlibint.h>
+# define _DRM_MALLOC Xmalloc
+# define _DRM_FREE Xfree
+# endif
+#endif
+
+/* Not all systems have MAP_FAILED defined */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#include "xf86drm.h"
+#include "xf86drmR128.h"
+#include "drm.h"
+
+int drmR128InitCCE(int fd, drmR128Init *info)
+{
+ drm_r128_init_t init;
+
+ memset(&init, 0, sizeof(drm_r128_init_t));
+
+ init.func = R128_INIT_CCE;
+ init.sarea_priv_offset = info->sarea_priv_offset;
+ init.is_pci = info->is_pci;
+ init.cce_mode = info->cce_mode;
+ init.cce_fifo_size = info->cce_fifo_size;
+ init.cce_secure = info->cce_secure;
+ init.ring_size = info->ring_size;
+ init.usec_timeout = info->usec_timeout;
+
+ init.fb_offset = info->fb_offset;
+ init.agp_ring_offset = info->agp_ring_offset;
+ init.agp_read_ptr_offset = info->agp_read_ptr_offset;
+ init.agp_vertbufs_offset = info->agp_vertbufs_offset;
+ init.agp_indbufs_offset = info->agp_indbufs_offset;
+ init.agp_textures_offset = info->agp_textures_offset;
+ init.mmio_offset = info->mmio_offset;
+
+ if (ioctl(fd, DRM_IOCTL_R128_INIT, &init)) return -errno;
+
+ return 0;
+}
+
+int drmR128CleanupCCE(int fd)
+{
+ drm_r128_init_t init;
+
+ memset(&init, 0, sizeof(drm_r128_init_t));
+
+ init.func = R128_CLEANUP_CCE;
+
+ if (ioctl(fd, DRM_IOCTL_R128_INIT, &init)) return -errno;
+
+ return 0;
+}
+
+int drmR128EngineReset(int fd)
+{
+ if (ioctl(fd, DRM_IOCTL_R128_RESET, NULL)) return -errno;
+
+ return 0;
+}
+
+int drmR128EngineFlush(int fd)
+{
+ if (ioctl(fd, DRM_IOCTL_R128_FLUSH, NULL)) return -errno;
+
+ return 0;
+}
+
+int drmR128CCEWaitForIdle(int fd)
+{
+ if (ioctl(fd, DRM_IOCTL_R128_CCEIDL, NULL)) return -errno;
+
+ return 0;
+}
+
+int drmR128SubmitPackets(int fd, CARD32 *buffer, int *count, int flags)
+{
+ drm_r128_packet_t packet;
+ int ret;
+
+ memset(&packet, 0, sizeof(drm_r128_packet_t));
+
+ packet.count = *count;
+ packet.flags = flags;
+
+ while (packet.count > 0) {
+ packet.buffer = buffer + (*count - packet.count);
+ ret = ioctl(fd, DRM_IOCTL_R128_PACKET, &packet);
+ if (ret < 0 && ret != -EAGAIN) {
+ *count = packet.count;
+ return -errno;
+ }
+ }
+
+ *count = 0;
+ return 0;
+}
+
+int drmR128GetVertexBuffers(int fd, int count, int *indices, int *sizes)
+{
+ drm_r128_vertex_t v;
+
+ v.send_count = 0;
+ v.send_indices = NULL;
+ v.send_sizes = NULL;
+ v.prim = DRM_R128_PRIM_NONE;
+ v.request_count = count;
+ v.request_indices = indices;
+ v.request_sizes = sizes;
+ v.granted_count = 0;
+
+ if (ioctl(fd, DRM_IOCTL_R128_VERTEX, &v)) return -errno;
+
+ return v.granted_count;
+}
+
+int drmR128FlushVertexBuffers(int fd, int count, int *indices,
+ int *sizes, drmR128PrimType prim)
+{
+ drm_r128_vertex_t v;
+
+ v.send_count = count;
+ v.send_indices = indices;
+ v.send_sizes = sizes;
+ v.prim = prim;
+ v.request_count = 0;
+ v.request_indices = NULL;
+ v.request_sizes = NULL;
+ v.granted_count = 0;
+
+ if (ioctl(fd, DRM_IOCTL_R128_VERTEX, &v) < 0) return -errno;
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmRandom.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmRandom.c
new file mode 100644
index 000000000..dad836d02
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmRandom.c
@@ -0,0 +1,219 @@
+/* xf86drmRandom.c -- "Minimal Standard" PRNG Implementation
+ * Created: Mon Apr 19 08:28:13 1999 by faith@precisioninsight.com
+ * Revised: Thu Jun 24 14:53:45 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRandom.c,v 1.4 1999/06/24 18:54:55 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRandom.c,v 1.2 1999/06/27 14:08:20 dawes Exp $
+ *
+ * DESCRIPTION
+ *
+ * This file contains a simple, straightforward implementation of the Park
+ * & Miller "Minimal Standard" PRNG [PM88, PMS93], which is a Lehmer
+ * multiplicative linear congruential generator (MLCG) with a period of
+ * 2^31-1.
+ *
+ * This implementation is intended to provide a reliable, portable PRNG
+ * that is suitable for testing a hash table implementation and for
+ * implementing skip lists.
+ *
+ * FUTURE ENHANCEMENTS
+ *
+ * If initial seeds are not selected randomly, two instances of the PRNG
+ * can be correlated. [Knuth81, pp. 32-33] describes a shuffling technique
+ * that can eliminate this problem.
+ *
+ * If PRNGs are used for simulation, the period of the current
+ * implementation may be too short. [LE88] discusses methods of combining
+ * MLCGs to produce much longer periods, and suggests some alternative
+ * values for A and M. [LE90 and Sch92] also provide information on
+ * long-period PRNGs.
+ *
+ * REFERENCES
+ *
+ * [Knuth81] Donald E. Knuth. The Art of Computer Programming. Volume 2:
+ * Seminumerical Algorithms. Reading, Massachusetts: Addison-Wesley, 1981.
+ *
+ * [LE88] Pierre L'Ecuyer. "Efficient and Portable Combined Random Number
+ * Generators". CACM 31(6), June 1988, pp. 742-774.
+ *
+ * [LE90] Pierre L'Ecuyer. "Random Numbers for Simulation". CACM 33(10,
+ * October 1990, pp. 85-97.
+ *
+ * [PM88] Stephen K. Park and Keith W. Miller. "Random Number Generators:
+ * Good Ones are Hard to Find". CACM 31(10), October 1988, pp. 1192-1201.
+ *
+ * [Sch92] Bruce Schneier. "Pseudo-Ransom Sequence Generator for 32-Bit
+ * CPUs". Dr. Dobb's Journal 17(2), February 1992, pp. 34, 37-38, 40.
+ *
+ * [PMS93] Stephen K. Park, Keith W. Miller, and Paul K. Stockmeyer. In
+ * "Technical Correspondence: Remarks on Choosing and Implementing Random
+ * Number Generators". CACM 36(7), July 1993, pp. 105-110.
+ *
+ */
+
+#define RANDOM_MAIN 0
+
+#if RANDOM_MAIN
+# include <stdio.h>
+# include <stdlib.h>
+#else
+# include "xf86drm.h"
+# ifdef XFree86LOADER
+# include "xf86.h"
+# include "xf86_ansic.h"
+# else
+# include <stdio.h>
+# include <stdlib.h>
+# endif
+#endif
+
+#define N(x) drm##x
+
+#define RANDOM_MAGIC 0xfeedbeef
+#define RANDOM_DEBUG 0
+
+#if RANDOM_MAIN
+#define RANDOM_ALLOC malloc
+#define RANDOM_FREE free
+#else
+#define RANDOM_ALLOC drmMalloc
+#define RANDOM_FREE drmFree
+#endif
+
+typedef struct RandomState {
+ unsigned long magic;
+ unsigned long a;
+ unsigned long m;
+ unsigned long q; /* m div a */
+ unsigned long r; /* m mod a */
+ unsigned long check;
+ long seed;
+} RandomState;
+
+#if RANDOM_MAIN
+extern void *N(RandomCreate)(unsigned long seed);
+extern int N(RandomDestroy)(void *state);
+extern unsigned long N(Random)(void *state);
+extern double N(RandomDouble)(void *state);
+#endif
+
+void *N(RandomCreate)(unsigned long seed)
+{
+ RandomState *state;
+
+ state = RANDOM_ALLOC(sizeof(*state));
+ if (!state) return NULL;
+ state->magic = RANDOM_MAGIC;
+#if 0
+ /* Park & Miller, October 1988 */
+ state->a = 16807;
+ state->m = 2147483647;
+ state->check = 1043618065; /* After 10000 iterations */
+#else
+ /* Park, Miller, and Stockmeyer, July 1993 */
+ state->a = 48271;
+ state->m = 2147483647;
+ state->check = 399268537; /* After 10000 iterations */
+#endif
+ state->q = state->m / state->a;
+ state->r = state->m % state->a;
+
+ state->seed = seed;
+ /* Check for illegal boundary conditions,
+ and choose closest legal value. */
+ if (state->seed <= 0) state->seed = 1;
+ if (state->seed >= state->m) state->seed = state->m - 1;
+
+ return state;
+}
+
+int N(RandomDestroy)(void *state)
+{
+ RANDOM_FREE(state);
+ return 0;
+}
+
+unsigned long N(Random)(void *state)
+{
+ RandomState *s = (RandomState *)state;
+ long hi;
+ long lo;
+
+ hi = s->seed / s->q;
+ lo = s->seed % s->q;
+ s->seed = s->a * lo - s->r * hi;
+ if (s->seed <= 0) s->seed += s->m;
+
+ return s->seed;
+}
+
+double N(RandomDouble)(void *state)
+{
+ RandomState *s = (RandomState *)state;
+
+ return (double)N(Random)(state)/(double)s->m;
+}
+
+#if RANDOM_MAIN
+static void check_period(long seed)
+{
+ unsigned long count = 0;
+ unsigned long initial;
+ void *state;
+
+ state = N(RandomCreate)(seed);
+ initial = N(Random)(state);
+ ++count;
+ while (initial != N(Random)(state)) {
+ if (!++count) break;
+ }
+ printf("With seed of %10ld, period = %10lu (0x%08lx)\n",
+ seed, count, count);
+ N(RandomDestroy)(state);
+}
+
+int main(void)
+{
+ RandomState *state;
+ int i;
+ unsigned long rand;
+
+ state = N(RandomCreate)(1);
+ for (i = 0; i < 10000; i++) {
+ rand = N(Random)(state);
+ }
+ printf("After 10000 iterations: %lu (%lu expected): %s\n",
+ rand, state->check,
+ rand - state->check ? "*INCORRECT*" : "CORRECT");
+ N(RandomDestroy)(state);
+
+ printf("Checking periods...\n");
+ check_period(1);
+ check_period(2);
+ check_period(31415926);
+
+ return 0;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmSL.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmSL.c
new file mode 100644
index 000000000..d5dd63da8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/xf86drmSL.c
@@ -0,0 +1,490 @@
+/* xf86drmSL.c -- Skip list support
+ * Created: Mon May 10 09:28:13 1999 by faith@precisioninsight.com
+ * Revised: Thu Jun 3 16:13:01 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSL.c,v 1.2 1999/06/07 13:01:42 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSL.c,v 1.1 1999/06/14 07:32:02 dawes Exp $
+ *
+ * DESCRIPTION
+ *
+ * This file contains a straightforward skip list implementation.n
+ *
+ * FUTURE ENHANCEMENTS
+ *
+ * REFERENCES
+ *
+ * [Pugh90] William Pugh. Skip Lists: A Probabilistic Alternative to
+ * Balanced Trees. CACM 33(6), June 1990, pp. 668-676.
+ *
+ */
+
+#define SL_MAIN 0
+
+#if SL_MAIN
+# include <stdio.h>
+# include <stdlib.h>
+# include <sys/time.h>
+#else
+# include "xf86drm.h"
+# ifdef XFree86LOADER
+# include "xf86.h"
+# include "xf86_ansic.h"
+# else
+# include <stdio.h>
+# include <stdlib.h>
+# endif
+#endif
+
+#define N(x) drm##x
+
+#define SL_LIST_MAGIC 0xfacade00LU
+#define SL_ENTRY_MAGIC 0x00fab1edLU
+#define SL_FREED_MAGIC 0xdecea5edLU
+#define SL_MAX_LEVEL 16
+#define SL_DEBUG 0
+#define SL_RANDOM_SEED 0xc01055a1LU
+
+#if SL_MAIN
+#define SL_ALLOC malloc
+#define SL_FREE free
+#define SL_RANDOM_DECL static int state = 0;
+#define SL_RANDOM_INIT(seed) if (!state) { srandom(seed); ++state; }
+#define SL_RANDOM random()
+#else
+#define SL_ALLOC drmMalloc
+#define SL_FREE drmFree
+#define SL_RANDOM_DECL static void *state = NULL
+#define SL_RANDOM_INIT(seed) if (!state) state = drmRandomCreate(seed)
+#define SL_RANDOM drmRandom(state)
+
+#endif
+
+typedef struct SLEntry {
+ unsigned long magic; /* SL_ENTRY_MAGIC */
+ unsigned long key;
+ void *value;
+ int levels;
+ struct SLEntry *forward[1]; /* variable sized array */
+} SLEntry, *SLEntryPtr;
+
+typedef struct SkipList {
+ unsigned long magic; /* SL_LIST_MAGIC */
+ int level;
+ int count;
+ SLEntryPtr head;
+ SLEntryPtr p0; /* Position for iteration */
+} SkipList, *SkipListPtr;
+
+#if SL_MAIN
+extern void *N(SLCreate)(void);
+extern int N(SLDestroy)(void *l);
+extern int N(SLLookup)(void *l, unsigned long key, void **value);
+extern int N(SLInsert)(void *l, unsigned long key, void *value);
+extern int N(SLDelete)(void *l, unsigned long key);
+extern int N(SLNext)(void *l, unsigned long *key, void **value);
+extern int N(SLFirst)(void *l, unsigned long *key, void **value);
+extern void N(SLDump)(void *l);
+extern int N(SLLookupNeighbors)(void *l, unsigned long key,
+ unsigned long *prev_key, void **prev_value,
+ unsigned long *next_key, void **next_value);
+#endif
+
+static SLEntryPtr SLCreateEntry(int max_level, unsigned long key, void *value)
+{
+ SLEntryPtr entry;
+
+ if (max_level < 0 || max_level > SL_MAX_LEVEL) max_level = SL_MAX_LEVEL;
+
+ entry = SL_ALLOC(sizeof(*entry)
+ + (max_level + 1) * sizeof(entry->forward[0]));
+ if (!entry) return NULL;
+ entry->magic = SL_ENTRY_MAGIC;
+ entry->key = key;
+ entry->value = value;
+ entry->levels = max_level + 1;
+
+ return entry;
+}
+
+static int SLRandomLevel(void)
+{
+ int level = 1;
+ SL_RANDOM_DECL;
+
+ SL_RANDOM_INIT(SL_RANDOM_SEED);
+
+ while ((SL_RANDOM & 0x01) && level < SL_MAX_LEVEL) ++level;
+ return level;
+}
+
+void *N(SLCreate)(void)
+{
+ SkipListPtr list;
+ int i;
+
+ list = SL_ALLOC(sizeof(*list));
+ if (!list) return NULL;
+ list->magic = SL_LIST_MAGIC;
+ list->level = 0;
+ list->head = SLCreateEntry(SL_MAX_LEVEL, 0, NULL);
+ list->count = 0;
+
+ for (i = 0; i <= SL_MAX_LEVEL; i++) list->head->forward[i] = NULL;
+
+ return list;
+}
+
+int N(SLDestroy)(void *l)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr entry;
+ SLEntryPtr next;
+
+ if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
+
+ for (entry = list->head; entry; entry = next) {
+ if (entry->magic != SL_ENTRY_MAGIC) return -1; /* Bad magic */
+ next = entry->forward[0];
+ entry->magic = SL_FREED_MAGIC;
+ SL_FREE(entry);
+ }
+
+ list->magic = SL_FREED_MAGIC;
+ SL_FREE(list);
+ return 0;
+}
+
+static SLEntryPtr SLLocate(void *l, unsigned long key, SLEntryPtr *update)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr entry;
+ int i;
+
+ if (list->magic != SL_LIST_MAGIC) return NULL;
+
+ for (i = list->level, entry = list->head; i >= 0; i--) {
+ while (entry->forward[i] && entry->forward[i]->key < key)
+ entry = entry->forward[i];
+ update[i] = entry;
+ }
+
+ return entry->forward[0];
+}
+
+int N(SLInsert)(void *l, unsigned long key, void *value)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr entry;
+ SLEntryPtr update[SL_MAX_LEVEL + 1];
+ int level;
+ int i;
+
+ if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
+
+ entry = SLLocate(list, key, update);
+
+ if (entry && entry->key == key) return 1; /* Already in list */
+
+
+ level = SLRandomLevel();
+ if (level > list->level) {
+ level = ++list->level;
+ update[level] = list->head;
+ }
+
+ entry = SLCreateEntry(level, key, value);
+
+ /* Fix up forward pointers */
+ for (i = 0; i <= level; i++) {
+ entry->forward[i] = update[i]->forward[i];
+ update[i]->forward[i] = entry;
+ }
+
+ ++list->count;
+ return 0; /* Added to table */
+}
+
+int N(SLDelete)(void *l, unsigned long key)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr update[SL_MAX_LEVEL + 1];
+ SLEntryPtr entry;
+ int i;
+
+ if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
+
+ entry = SLLocate(list, key, update);
+
+ if (!entry || entry->key != key) return 1; /* Not found */
+
+ /* Fix up forward pointers */
+ for (i = 0; i <= list->level; i++) {
+ if (update[i]->forward[i] == entry)
+ update[i]->forward[i] = entry->forward[i];
+ }
+
+ entry->magic = SL_FREED_MAGIC;
+ SL_FREE(entry);
+
+ while (list->level && !list->head->forward[list->level]) --list->level;
+ --list->count;
+ return 0;
+}
+
+int N(SLLookup)(void *l, unsigned long key, void **value)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr update[SL_MAX_LEVEL + 1];
+ SLEntryPtr entry;
+
+ entry = SLLocate(list, key, update);
+
+ if (entry && entry->key == key) {
+ *value = entry;
+ return 0;
+ }
+ *value = NULL;
+ return -1;
+}
+
+int N(SLLookupNeighbors)(void *l, unsigned long key,
+ unsigned long *prev_key, void **prev_value,
+ unsigned long *next_key, void **next_value)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr update[SL_MAX_LEVEL + 1];
+ SLEntryPtr entry;
+ int retcode = 0;
+
+ entry = SLLocate(list, key, update);
+
+ *prev_key = *next_key = key;
+ *prev_value = *next_value = NULL;
+
+ if (update[0]) {
+ *prev_key = update[0]->key;
+ *prev_value = update[0]->value;
+ ++retcode;
+ if (update[0]->forward[0]) {
+ *next_key = update[0]->forward[0]->key;
+ *next_value = update[0]->forward[0]->value;
+ ++retcode;
+ }
+ }
+ return retcode;
+}
+
+int N(SLNext)(void *l, unsigned long *key, void **value)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr entry;
+
+ if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
+
+ entry = list->p0;
+
+ if (entry) {
+ list->p0 = entry->forward[0];
+ *key = entry->key;
+ *value = entry->value;
+ return 1;
+ }
+ list->p0 = NULL;
+ return 0;
+}
+
+int N(SLFirst)(void *l, unsigned long *key, void **value)
+{
+ SkipListPtr list = (SkipListPtr)l;
+
+ if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
+
+ list->p0 = list->head->forward[0];
+ return N(SLNext)(list, key, value);
+}
+
+/* Dump internal data structures for debugging. */
+void N(SLDump)(void *l)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr entry;
+ int i;
+
+ if (list->magic != SL_LIST_MAGIC) {
+ printf("Bad magic: 0x%08lx (expected 0x%08lx)\n",
+ list->magic, SL_LIST_MAGIC);
+ return;
+ }
+
+ printf("Level = %d, count = %d\n", list->level, list->count);
+ for (entry = list->head; entry; entry = entry->forward[0]) {
+ if (entry->magic != SL_ENTRY_MAGIC) {
+ printf("Bad magic: 0x%08lx (expected 0x%08lx)\n",
+ list->magic, SL_ENTRY_MAGIC);
+ }
+ printf("\nEntry %p <0x%08lx, %p> has %2d levels\n",
+ entry, entry->key, entry->value, entry->levels);
+ for (i = 0; i < entry->levels; i++) {
+ if (entry->forward[i]) {
+ printf(" %2d: %p <0x%08lx, %p>\n",
+ i,
+ entry->forward[i],
+ entry->forward[i]->key,
+ entry->forward[i]->value);
+ } else {
+ printf(" %2d: %p\n", i, entry->forward[i]);
+ }
+ }
+ }
+}
+
+#if SL_MAIN
+static void print(SkipListPtr list)
+{
+ unsigned long key;
+ void *value;
+
+ if (N(SLFirst)(list, &key, &value)) {
+ do {
+ printf("key = %5lu, value = %p\n", key, value);
+ } while (N(SLNext)(list, &key, &value));
+ }
+}
+
+static double do_time(int size, int iter)
+{
+ SkipListPtr list;
+ int i, j;
+ unsigned long keys[1000000];
+ unsigned long previous;
+ unsigned long key;
+ void *value;
+ struct timeval start, stop;
+ double usec;
+ SL_RANDOM_DECL;
+
+ SL_RANDOM_INIT(12345);
+
+ list = N(SLCreate)();
+
+ for (i = 0; i < size; i++) {
+ keys[i] = SL_RANDOM;
+ N(SLInsert)(list, keys[i], NULL);
+ }
+
+ previous = 0;
+ if (N(SLFirst)(list, &key, &value)) {
+ do {
+ if (key <= previous) {
+ printf( "%lu !< %lu\n", previous, key);
+ }
+ previous = key;
+ } while (N(SLNext)(list, &key, &value));
+ }
+
+ gettimeofday(&start, NULL);
+ for (j = 0; j < iter; j++) {
+ for (i = 0; i < size; i++) {
+ if (N(SLLookup)(list, keys[i], &value))
+ printf("Error %lu %d\n", keys[i], i);
+ }
+ }
+ gettimeofday(&stop, NULL);
+
+ usec = (double)(stop.tv_sec * 1000000 + stop.tv_usec
+ - start.tv_sec * 1000000 - start.tv_usec) / (size * iter);
+
+ printf("%0.2f microseconds for list length %d\n", usec, size);
+
+ N(SLDestroy)(list);
+
+ return usec;
+}
+
+static void print_neighbors(void *list, unsigned long key)
+{
+ unsigned long prev_key = 0;
+ unsigned long next_key = 0;
+ void *prev_value;
+ void *next_value;
+ int retval;
+
+ retval = drmSLLookupNeighbors(list, key,
+ &prev_key, &prev_value,
+ &next_key, &next_value);
+ printf("Neighbors of %5lu: %d %5lu %5lu\n",
+ key, retval, prev_key, next_key);
+}
+
+int main(void)
+{
+ SkipListPtr list;
+ double usec, usec2, usec3, usec4;
+
+ list = N(SLCreate)();
+ printf( "list at %p\n", list);
+
+ print(list);
+ printf("\n==============================\n\n");
+
+ N(SLInsert)(list, 123, NULL);
+ N(SLInsert)(list, 213, NULL);
+ N(SLInsert)(list, 50, NULL);
+ print(list);
+ printf("\n==============================\n\n");
+
+ print_neighbors(list, 0);
+ print_neighbors(list, 50);
+ print_neighbors(list, 51);
+ print_neighbors(list, 123);
+ print_neighbors(list, 200);
+ print_neighbors(list, 213);
+ print_neighbors(list, 256);
+ printf("\n==============================\n\n");
+
+ N(SLDelete)(list, 50);
+ print(list);
+ printf("\n==============================\n\n");
+
+ N(SLDump)(list);
+ N(SLDestroy)(list);
+ printf("\n==============================\n\n");
+
+ usec = do_time(100, 10000);
+ usec2 = do_time(1000, 500);
+ printf("Table size increased by %0.2f, search time increased by %0.2f\n",
+ 1000.0/100.0, usec2 / usec);
+
+ usec3 = do_time(10000, 50);
+ printf("Table size increased by %0.2f, search time increased by %0.2f\n",
+ 10000.0/100.0, usec3 / usec);
+
+ usec4 = do_time(100000, 4);
+ printf("Table size increased by %0.2f, search time increased by %0.2f\n",
+ 100000.0/100.0, usec4 / usec);
+
+ return 0;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile
index 96388450b..fdaecb972 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile
@@ -13,15 +13,16 @@ MOBJ = drmmodule.o
MTRR_DEFINES = -DHAS_MTRR_SUPPORT
#endif
-SRCS = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c $(MSRC)
-OBJS = xf86drm.o xf86drmHash.o xf86drmRandom.o xf86drmSL.o $(MOBJ)
-
+SRCS = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c xf86drmI810.c xf86drmMga.c xf86drmR128.c $(MSRC)
+OBJS = xf86drm.o xf86drmHash.o xf86drmRandom.o xf86drmSL.o xf86drmI810.o xf86drmMga.o xf86drmR128.o $(MOBJ)
INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
-I$(XINCLUDESRC) -I$(EXTINCSRC) -I../.. -Ikernel
DEFINES = $(MTRR_DEFINES) $(GLX_DEFINES)
+#if DoLoadableServer
+
ModuleObjectRule()
LibraryModuleTarget(drm,$(OBJS))
NormalLintTarget($(SRCS))
@@ -30,6 +31,14 @@ NormalLintTarget($(SRCS))
InstallLibraryModule(drm,$(MODULEDIR),linux)
#endif
+#else
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+
+#endif
+
+
#define IHaveSubdirs
SUBDIRS = kernel
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel
index 44d75c487..a169473af 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel
@@ -14,7 +14,8 @@
L_TARGET := libdrm.a
L_OBJS := init.o memory.o proc.o auth.o context.o drawable.o bufs.o \
- lists.o lock.o ioctl.o fops.o vm.o dma.o
+ lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o \
+ agpsupport.o
M_OBJS :=
@@ -26,6 +27,14 @@ ifdef CONFIG_DRM_TDFX
M_OBJS += tdfx.o
endif
+ifdef CONFIG_DRM_MGA
+M_OBJS += mga.o
+endif
+
+ifdef CONFIG_DRM_R128
+M_OBJS += r128.o
+endif
+
include $(TOPDIR)/Rules.make
gamma.o: gamma_drv.o gamma_dma.o $(L_TARGET)
@@ -33,3 +42,12 @@ gamma.o: gamma_drv.o gamma_dma.o $(L_TARGET)
tdfx.o: tdfx_drv.o tdfx_context.o $(L_TARGET)
$(LD) $(LD_RFLAG) -r -o $@ tdfx_drv.o tdfx_context.o -L. -ldrm
+
+i810.o: i810_drv.o i810_context.o $(L_TARGET)
+ $(LD) $(LD_RFLAG) -r -o $@ i810_drv.o i810_bufs.o i810_dma.o i810_context.o -L. -ldrm
+
+mga.o: mga_drv.o mga_context.o mga_dma.o mga_bufs.o $(L_TARGET)
+ $(LD) $(LD_RFLAG) -r -o $@ mga_drv.o mga_bufs.o mga_dma.o mga_context.o mga_state.o -L. -ldrm
+
+r128.o: r128_drv.o r128_context.o $(L_TARGET)
+ $(LD) $(LD_RFLAG) -r -o $@ r128_drv.o r128_context.o -L. -ldrm
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux
index 9810fe3d5..ecc196bdd 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux
@@ -47,7 +47,7 @@
# **** End of SMP/MODVERSIONS detection
-MODS= gamma.o tdfx.o
+MODS= gamma.o tdfx.o r128.o
LIBS= libdrm.a
PROGS= drmstat
@@ -61,6 +61,9 @@ GAMMAHEADERS= gamma_drv.h $(DRMHEADERS)
TDFXOBJS= tdfx_drv.o tdfx_context.o
TDFXHEADERS= tdfx_drv.h $(DRMHEADERS)
+R128OBJS= r128_drv.o r128_dma.o r128_bufs.o r128_context.o
+R128HEADERS= r128_drv.h r128_drm.h $(DRMHEADERS)
+
PROGOBJS= drmstat.po xf86drm.po xf86drmHash.po xf86drmRandom.po sigio.po
PROGHEADERS= xf86drm.h $(DRMHEADERS)
@@ -167,6 +170,9 @@ gamma.o: $(GAMMAOBJS) $(LIBS)
tdfx.o: $(TDFXOBJS) $(LIBS)
$(LD) -r $^ -o $@
+r128.o: $(R128OBJS) $(LIBS)
+ $(LD) -r $^ -o $@
+
ifeq ($(AGP),1)
mga.o: $(MGAOBJS) $(LIBS)
$(LD) -r $^ -o $@
@@ -196,6 +202,7 @@ ChangeLog:
$(DRMOBJS): $(DRMHEADERS)
$(GAMMAOBJS): $(GAMMAHEADERS)
$(TDFXOBJS): $(TDFXHEADERS)
+$(R128OBJS): $(R128HEADERS)
ifeq ($(AGP),1)
$(MGAOBJS): $(MGAHEADERS)
$(I810OBJS): $(I810HEADERS)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/agpsupport.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/agpsupport.c
index 262d63adf..c89c3e258 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/agpsupport.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/agpsupport.c
@@ -238,6 +238,8 @@ int drm_agp_bind(struct inode *inode, struct file *filp, unsigned int cmd,
page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
if ((retcode = drm_bind_agp(entry->memory, page))) return retcode;
entry->bound = dev->agp->base + (page << PAGE_SHIFT);
+ DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n",
+ dev->agp->base, entry->bound);
return 0;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
index 15491aeeb..c8c5581da 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
@@ -72,9 +72,10 @@ typedef struct drm_clip_rect {
unsigned short y2;
} drm_clip_rect_t;
-/* Seperate include files for the i810/mga specific structures */
+/* Seperate include files for the i810/mga/r128 specific structures */
#include "mga_drm.h"
#include "i810_drm.h"
+#include "r128_drm.h"
typedef struct drm_version {
int version_major; /* Major version */
@@ -297,7 +298,7 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t)
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t)
-#define DRM_IOCTL_GET_MAGIC DRM_IOW( 0x02, drm_auth_t)
+#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t)
#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t)
@@ -328,11 +329,11 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
-#define DRM_IOCTL_AGP_ENABLE DRM_IOR( 0x32, drm_agp_mode_t)
-#define DRM_IOCTL_AGP_INFO DRM_IOW( 0x33, drm_agp_info_t)
+#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t)
+#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t)
#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t)
-#define DRM_IOCTL_AGP_BIND DRM_IOWR(0x36, drm_agp_binding_t)
+#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
/* Mga specific ioctls */
@@ -342,12 +343,23 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t)
#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t)
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t )
+#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
/* I810 specific ioctls */
#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
-#define DRM_IOCTL_I810_DMA DRM_IOW( 0x42, drm_i810_general_t)
+#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t)
#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43)
#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44)
+#define DRM_IOCTL_I810_GETBUF DRM_IOW( 0x45, drm_i810_dma_t)
+#define DRM_IOCTL_I810_SWAP DRM_IO ( 0x46)
+
+/* Rage 128 specific ioctls */
+#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
+#define DRM_IOCTL_R128_RESET DRM_IO( 0x41)
+#define DRM_IOCTL_R128_FLUSH DRM_IO( 0x42)
+#define DRM_IOCTL_R128_CCEIDL DRM_IO( 0x43)
+#define DRM_IOCTL_R128_PACKET DRM_IOW( 0x44, drm_r128_packet_t)
+#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x45, drm_r128_vertex_t)
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
index ecf50436d..350d1ef9b 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
@@ -229,8 +229,8 @@ typedef struct drm_magic_entry {
} drm_magic_entry_t;
typedef struct drm_magic_head {
- struct drm_magic_entry *head;
- struct drm_magic_entry *tail;
+ struct drm_magic_entry *head;
+ struct drm_magic_entry *tail;
} drm_magic_head_t;
typedef struct drm_vma_entry {
@@ -263,16 +263,15 @@ typedef struct drm_buf {
DRM_LIST_RECLAIM = 5
} list; /* Which list we're on */
-
- void *dev_private;
- int dev_priv_size;
-
#if DRM_DMA_HISTOGRAM
cycles_t time_queued; /* Queued to kernel DMA queue */
cycles_t time_dispatched; /* Dispatched to hardware */
cycles_t time_completed; /* Completed by hardware */
cycles_t time_freed; /* Back on freelist */
#endif
+
+ int dev_priv_size; /* Size of buffer private stoarge */
+ void *dev_private; /* Per-buffer private storage */
} drm_buf_t;
#if DRM_DMA_HISTOGRAM
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c
index 3372f51ea..eb78c0374 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c
@@ -88,13 +88,31 @@ static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address,
GAMMA_WRITE(GAMMA_DMACOUNT, length / 4);
}
-static inline void gamma_dma_quiescent(drm_device_t *dev)
+static inline void gamma_dma_quiescent_single(drm_device_t *dev)
{
while (GAMMA_READ(GAMMA_DMACOUNT))
;
while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
;
+
+ GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10);
+ GAMMA_WRITE(GAMMA_SYNC, 0);
+
+ do {
+ while (!GAMMA_READ(GAMMA_OUTFIFOWORDS))
+ ;
+ } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG);
+}
+
+static inline void gamma_dma_quiescent_dual(drm_device_t *dev)
+{
+ while (GAMMA_READ(GAMMA_DMACOUNT))
+ ;
+ while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
+ ;
+
GAMMA_WRITE(GAMMA_BROADCASTMASK, 3);
+
GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10);
GAMMA_WRITE(GAMMA_SYNC, 0);
@@ -104,7 +122,6 @@ static inline void gamma_dma_quiescent(drm_device_t *dev)
;
} while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG);
-
/* Read from second MX */
do {
while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000))
@@ -789,8 +806,13 @@ int gamma_lock(struct inode *inode, struct file *filp, unsigned int cmd,
if (!ret) {
if (lock.flags & _DRM_LOCK_READY)
gamma_dma_ready(dev);
- if (lock.flags & _DRM_LOCK_QUIESCENT)
- gamma_dma_quiescent(dev);
+ if (lock.flags & _DRM_LOCK_QUIESCENT) {
+ if (gamma_found() == 1) {
+ gamma_dma_quiescent_single(dev);
+ } else {
+ gamma_dma_quiescent_dual(dev);
+ }
+ }
}
DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c
index c6838cb74..d42cf4aea 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c
@@ -32,6 +32,7 @@
#define EXPORT_SYMTAB
#include "drmP.h"
#include "gamma_drv.h"
+#include <linux/pci.h>
EXPORT_SYMBOL(gamma_init);
EXPORT_SYMBOL(gamma_cleanup);
@@ -99,10 +100,13 @@ static drm_ioctl_desc_t gamma_ioctls[] = {
int init_module(void);
void cleanup_module(void);
static char *gamma = NULL;
+static int devices = 0;
MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas.");
MODULE_DESCRIPTION("3dlabs GMX 2000");
MODULE_PARM(gamma, "s");
+MODULE_PARM(devices, "i");
+MODULE_PARM_DESC(devices, "devices=x, where x is the number of MX chips on your card\n");
/* init_module is called when insmod is used to load the module */
@@ -317,6 +321,34 @@ static int gamma_takedown(drm_device_t *dev)
return 0;
}
+int gamma_found(void)
+{
+ return devices;
+}
+
+int gamma_find_devices(void)
+{
+ struct pci_dev *d = NULL, *one = NULL, *two = NULL;
+
+ d = pci_find_device(PCI_VENDOR_ID_3DLABS,PCI_DEVICE_ID_3DLABS_GAMMA,d);
+ if (!d) return 0;
+
+ one = pci_find_device(PCI_VENDOR_ID_3DLABS,PCI_DEVICE_ID_3DLABS_MX,d);
+ if (!one) return 0;
+
+ /* Make sure it's on the same card, if not - no MX's found */
+ if (PCI_SLOT(d->devfn) != PCI_SLOT(one->devfn)) return 0;
+
+ two = pci_find_device(PCI_VENDOR_ID_3DLABS,PCI_DEVICE_ID_3DLABS_MX,one);
+ if (!two) return 1;
+
+ /* Make sure it's on the same card, if not - only 1 MX found */
+ if (PCI_SLOT(d->devfn) != PCI_SLOT(two->devfn)) return 1;
+
+ /* Two MX's found - we don't currently support more than 2 */
+ return 2;
+}
+
/* gamma_init is called via init_module at module load time, or via
* linux/init/main.c (this is not currently supported). */
@@ -334,6 +366,8 @@ int gamma_init(void)
#ifdef MODULE
drm_parse_options(gamma);
#endif
+ devices = gamma_find_devices();
+ if (devices == 0) return -1;
if ((retcode = misc_register(&gamma_misc))) {
DRM_ERROR("Cannot register \"%s\"\n", GAMMA_NAME);
@@ -345,13 +379,14 @@ int gamma_init(void)
drm_mem_init();
drm_proc_init(dev);
- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d with %d MX devices\n",
GAMMA_NAME,
GAMMA_MAJOR,
GAMMA_MINOR,
GAMMA_PATCHLEVEL,
GAMMA_DATE,
- gamma_misc.minor);
+ gamma_misc.minor,
+ devices);
return 0;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h
index 622cedfe3..55dc26bec 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h
@@ -51,5 +51,7 @@ extern int gamma_irq_install(drm_device_t *dev, int irq);
extern int gamma_irq_uninstall(drm_device_t *dev);
extern int gamma_control(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
+extern int gamma_find_devices(void);
+extern int gamma_found(void);
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c
index 315f34378..fa1f84dcd 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c
@@ -119,6 +119,7 @@ int i810_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
buf->dev_private = drm_alloc(sizeof(drm_i810_buf_priv_t),
DRM_MEM_BUFS);
buf->dev_priv_size = sizeof(drm_i810_buf_priv_t);
+ memset(buf->dev_private, 0, sizeof(drm_i810_buf_priv_t));
#if DRM_DMA_HISTOGRAM
buf->time_queued = 0;
@@ -331,113 +332,3 @@ int i810_freebufs(struct inode *inode, struct file *filp, unsigned int cmd,
return 0;
}
-int i810_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_device_dma_t *dma = dev->dma;
- int retcode = 0;
- const int zero = 0;
- unsigned long virtual;
- unsigned long address;
- drm_buf_map_t request;
- int i;
-
- if (!dma) return -EINVAL;
-
- DRM_DEBUG("\n");
-
- spin_lock(&dev->count_lock);
- if (atomic_read(&dev->buf_alloc)) {
- spin_unlock(&dev->count_lock);
- DRM_DEBUG("Busy\n");
- return -EBUSY;
- }
- ++dev->buf_use; /* Can't allocate more after this call */
- spin_unlock(&dev->count_lock);
-
- copy_from_user_ret(&request,
- (drm_buf_map_t *)arg,
- sizeof(request),
- -EFAULT);
- DRM_DEBUG("dma->flags : %lx\n", dma->flags);
- if (request.count >= dma->buf_count) {
- if(dma->flags & _DRM_DMA_USE_AGP) {
- drm_i810_private_t *dev_priv =
- (drm_i810_private_t *)dev->dev_private;
- drm_map_t *map = NULL;
-
- map = dev->maplist[dev_priv->buffer_map_idx];
- if (!map) {
- DRM_DEBUG("map is null\n");
- retcode = -EINVAL;
- goto done;
- }
- DRM_DEBUG("map->offset : %lx\n", map->offset);
- DRM_DEBUG("map->size : %lx\n", map->size);
- DRM_DEBUG("map->type : %d\n", map->type);
- DRM_DEBUG("map->flags : %x\n", map->flags);
- DRM_DEBUG("map->handle : %lx\n", map->handle);
- DRM_DEBUG("map->mtrr : %d\n", map->mtrr);
- down(&current->mm->mmap_sem);
- virtual = do_mmap(filp, 0, map->size,
- PROT_READ|PROT_WRITE,
- MAP_SHARED,
- (unsigned long)map->offset);
-
- up(&current->mm->mmap_sem);
- } else {
- down(&current->mm->mmap_sem);
- virtual = do_mmap(filp, 0, dma->byte_count,
- PROT_READ|PROT_WRITE, MAP_SHARED, 0);
- up(&current->mm->mmap_sem);
- }
- if (virtual > -1024UL) {
- /* Real error */
- DRM_DEBUG("mmap error\n");
- retcode = (signed long)virtual;
- goto done;
- }
- request.virtual = (void *)virtual;
-
- for (i = 0; i < dma->buf_count; i++) {
- if (copy_to_user(&request.list[i].idx,
- &dma->buflist[i]->idx,
- sizeof(request.list[0].idx))) {
- retcode = -EFAULT;
- goto done;
- }
- if (copy_to_user(&request.list[i].total,
- &dma->buflist[i]->total,
- sizeof(request.list[0].total))) {
- retcode = -EFAULT;
- goto done;
- }
- if (copy_to_user(&request.list[i].used,
- &zero,
- sizeof(zero))) {
- retcode = -EFAULT;
- goto done;
- }
- address = virtual + dma->buflist[i]->offset;
- if (copy_to_user(&request.list[i].address,
- &address,
- sizeof(address))) {
- retcode = -EFAULT;
- goto done;
- }
- }
- }
- done:
- request.count = dma->buf_count;
- DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
-
- copy_to_user_ret((drm_buf_map_t *)arg,
- &request,
- sizeof(request),
- -EFAULT);
-
- DRM_DEBUG("retcode : %d\n", retcode);
- return retcode;
-}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c
index d82ed049e..94f35b61c 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c
@@ -36,8 +36,17 @@
#include <linux/interrupt.h> /* For task queue support */
-#define I810_BUF_FREE 1
-#define I810_BUF_USED 0
+/* in case we don't have a 2.3.99-pre6 kernel or later: */
+#ifndef VM_DONTCOPY
+#define VM_DONTCOPY 0
+#endif
+
+#define I810_BUF_FREE 2
+#define I810_BUF_CLIENT 1
+#define I810_BUF_HARDWARE 0
+
+#define I810_BUF_UNMAPPED 0
+#define I810_BUF_MAPPED 1
#define I810_REG(reg) 2
#define I810_BASE(reg) ((unsigned long) \
@@ -90,7 +99,7 @@ static inline void i810_print_status_page(drm_device_t *dev)
DRM_DEBUG( "hw_status: Reserved : %x\n", temp[3]);
DRM_DEBUG( "hw_status: Driver Counter : %d\n", temp[5]);
for(i = 6; i < dma->buf_count + 6; i++) {
- DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 6, temp[i]);
+ DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 6, temp[i]);
}
}
@@ -107,7 +116,7 @@ static drm_buf_t *i810_freelist_get(drm_device_t *dev)
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
/* In use is already a pointer */
used = cmpxchg(buf_priv->in_use, I810_BUF_FREE,
- I810_BUF_USED);
+ I810_BUF_CLIENT);
if(used == I810_BUF_FREE) {
return buf;
}
@@ -125,8 +134,8 @@ static int i810_freelist_put(drm_device_t *dev, drm_buf_t *buf)
int used;
/* In use is already a pointer */
- used = cmpxchg(buf_priv->in_use, I810_BUF_USED, I810_BUF_FREE);
- if(used != I810_BUF_USED) {
+ used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE);
+ if(used != I810_BUF_CLIENT) {
DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx);
return -EINVAL;
}
@@ -134,26 +143,114 @@ static int i810_freelist_put(drm_device_t *dev, drm_buf_t *buf)
return 0;
}
-static int i810_dma_get_buffers(drm_device_t *dev, drm_dma_t *d)
+static struct file_operations i810_buffer_fops = {
+ open: i810_open,
+ flush: drm_flush,
+ release: i810_release,
+ ioctl: i810_ioctl,
+ mmap: i810_mmap_buffers,
+ read: drm_read,
+ fasync: drm_fasync,
+ poll: drm_poll,
+};
+
+int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_buf_t *buf = dev_priv->mmap_buffer;
+ drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+
+ vma->vm_flags |= (VM_IO | VM_DONTCOPY);
+ vma->vm_file = filp;
+
+ buf_priv->currently_mapped = I810_BUF_MAPPED;
+
+ if (remap_page_range(vma->vm_start,
+ VM_OFFSET(vma),
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot)) return -EAGAIN;
+ return 0;
+}
+
+static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ struct file_operations *old_fops;
+ int retcode = 0;
+
+ if(buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL;
+ down(&current->mm->mmap_sem);
+ old_fops = filp->f_op;
+ filp->f_op = &i810_buffer_fops;
+ dev_priv->mmap_buffer = buf;
+ buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total,
+ PROT_READ|PROT_WRITE,
+ MAP_SHARED,
+ buf->bus_address);
+ dev_priv->mmap_buffer = NULL;
+ filp->f_op = old_fops;
+ if ((unsigned long)buf_priv->virtual > -1024UL) {
+ /* Real error */
+ DRM_DEBUG("mmap error\n");
+ retcode = (signed int)buf_priv->virtual;
+ buf_priv->virtual = 0;
+ }
+ up(&current->mm->mmap_sem);
+ return retcode;
+}
+
+static int i810_unmap_buffer(drm_buf_t *buf)
+{
+ drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ int retcode = 0;
+
+ if(buf_priv->currently_mapped != I810_BUF_MAPPED) return -EINVAL;
+ down(&current->mm->mmap_sem);
+ retcode = do_munmap((unsigned long)buf_priv->virtual,
+ (size_t) buf->total);
+ buf_priv->currently_mapped = I810_BUF_UNMAPPED;
+ buf_priv->virtual = 0;
+ up(&current->mm->mmap_sem);
+
+ return retcode;
+}
+
+static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d,
+ struct file *filp)
{
- int i;
+ drm_file_t *priv = filp->private_data;
drm_buf_t *buf;
+ drm_i810_buf_priv_t *buf_priv;
+ int retcode = 0;
- for (i = d->granted_count; i < d->request_count; i++) {
- buf = i810_freelist_get(dev);
- if (!buf) break;
- buf->pid = current->pid;
- copy_to_user_ret(&d->request_indices[i],
- &buf->idx,
- sizeof(buf->idx),
- -EFAULT);
- copy_to_user_ret(&d->request_sizes[i],
- &buf->total,
- sizeof(buf->total),
- -EFAULT);
- ++d->granted_count;
+ buf = i810_freelist_get(dev);
+ if (!buf) {
+ retcode = -ENOMEM;
+ DRM_DEBUG("%s retcode %d\n", __FUNCTION__, retcode);
+ goto out_get_buf;
}
- return 0;
+
+ retcode = i810_map_buffer(buf, filp);
+ if(retcode) {
+ i810_freelist_put(dev, buf);
+ DRM_DEBUG("mapbuf failed in %s retcode %d\n",
+ __FUNCTION__, retcode);
+ goto out_get_buf;
+ }
+ buf->pid = priv->pid;
+ buf_priv = buf->dev_private;
+ d->granted = 1;
+ d->request_idx = buf->idx;
+ d->request_size = buf->total;
+ d->virtual = buf_priv->virtual;
+
+out_get_buf:
+ return retcode;
}
static unsigned long i810_alloc_page(drm_device_t *dev)
@@ -184,7 +281,10 @@ static void i810_free_page(drm_device_t *dev, unsigned long page)
static int i810_dma_cleanup(drm_device_t *dev)
{
+ drm_device_dma_t *dma = dev->dma;
+
if(dev->dev_private) {
+ int i;
drm_i810_private_t *dev_priv =
(drm_i810_private_t *) dev->dev_private;
@@ -200,6 +300,12 @@ static int i810_dma_cleanup(drm_device_t *dev)
drm_free(dev->dev_private, sizeof(drm_i810_private_t),
DRM_MEM_DRIVER);
dev->dev_private = NULL;
+
+ for (i = 0; i < dma->buf_count; i++) {
+ drm_buf_t *buf = dma->buflist[ i ];
+ drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+ drm_ioremapfree(buf_priv->kernel_virtual, buf->total);
+ }
}
return 0;
}
@@ -210,6 +316,7 @@ static int i810_wait_ring(drm_device_t *dev, int n)
drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
int iters = 0;
unsigned long end;
+ unsigned int last_head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
end = jiffies + (HZ*3);
while (ring->space < n) {
@@ -217,9 +324,11 @@ static int i810_wait_ring(drm_device_t *dev, int n)
ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
ring->space = ring->head - (ring->tail+8);
+ if (ring->space < 0) ring->space += ring->Size;
- if (ring->space < 0) ring->space += ring->Size;
-
+ if (ring->head != last_head)
+ end = jiffies + (HZ*3);
+
iters++;
if((signed)(end - jiffies) <= 0) {
DRM_ERROR("space: %d wanted %d\n", ring->space, n);
@@ -249,9 +358,9 @@ static int i810_freelist_init(drm_device_t *dev)
{
drm_device_dma_t *dma = dev->dma;
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
- u8 *hw_status = (u8 *)dev_priv->hw_status_page;
- int i;
int my_idx = 24;
+ u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx);
+ int i;
if(dma->buf_count > 1019) {
/* Not enough space in the status page for the freelist */
@@ -262,11 +371,14 @@ static int i810_freelist_init(drm_device_t *dev)
drm_buf_t *buf = dma->buflist[ i ];
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
- buf_priv->in_use = hw_status + my_idx;
- DRM_DEBUG("buf_priv->in_use : %p\n", buf_priv->in_use);
- *buf_priv->in_use = I810_BUF_FREE;
+ buf_priv->in_use = hw_status++;
buf_priv->my_use_idx = my_idx;
my_idx += 4;
+
+ *buf_priv->in_use = I810_BUF_FREE;
+
+ buf_priv->kernel_virtual = drm_ioremap(buf->bus_address,
+ buf->total);
}
return 0;
}
@@ -300,9 +412,11 @@ static int i810_dma_initialize(drm_device_t *dev,
dev_priv->ring.Start = init->ring_start;
dev_priv->ring.End = init->ring_end;
dev_priv->ring.Size = init->ring_size;
+
dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base +
init->ring_start,
init->ring_size);
+
dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
if (dev_priv->ring.virtual_start == NULL) {
@@ -311,6 +425,17 @@ static int i810_dma_initialize(drm_device_t *dev,
" ring buffer\n");
return -ENOMEM;
}
+
+ dev_priv->w = init->w;
+ dev_priv->h = init->h;
+ dev_priv->pitch = init->pitch;
+ dev_priv->back_offset = init->back_offset;
+ dev_priv->depth_offset = init->depth_offset;
+
+ dev_priv->front_di1 = init->front_offset | init->pitch_bits;
+ dev_priv->back_di1 = init->back_offset | init->pitch_bits;
+ dev_priv->zi1 = init->depth_offset | init->pitch_bits;
+
/* Program Hardware Status Page */
dev_priv->hw_status_page = i810_alloc_page(dev);
@@ -365,37 +490,270 @@ int i810_dma_init(struct inode *inode, struct file *filp,
return retcode;
}
-static void i810_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf,
- int used )
+
+
+/* Most efficient way to verify state for the i810 is as it is
+ * emitted. Non-conformant state is silently dropped.
+ *
+ * Use 'volatile' & local var tmp to force the emitted values to be
+ * identical to the verified ones.
+ */
+static void i810EmitContextVerified( drm_device_t *dev,
+ volatile unsigned int *code )
+{
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ int i, j = 0;
+ unsigned int tmp;
+ RING_LOCALS;
+
+ BEGIN_LP_RING( I810_CTX_SETUP_SIZE );
+
+ OUT_RING( GFX_OP_COLOR_FACTOR );
+ OUT_RING( code[I810_CTXREG_CF1] );
+
+ OUT_RING( GFX_OP_STIPPLE );
+ OUT_RING( code[I810_CTXREG_ST1] );
+
+ for ( i = 4 ; i < I810_CTX_SETUP_SIZE ; i++ ) {
+ tmp = code[i];
+
+ if ((tmp & (7<<29)) == (3<<29) &&
+ (tmp & (0x1f<<24)) < (0x1d<<24))
+ {
+ OUT_RING( tmp );
+ j++;
+ }
+ }
+
+ if (j & 1)
+ OUT_RING( 0 );
+
+ ADVANCE_LP_RING();
+}
+
+static void i810EmitTexVerified( drm_device_t *dev,
+ volatile unsigned int *code )
+{
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ int i, j = 0;
+ unsigned int tmp;
+ RING_LOCALS;
+
+ BEGIN_LP_RING( I810_TEX_SETUP_SIZE );
+
+ OUT_RING( GFX_OP_MAP_INFO );
+ OUT_RING( code[I810_TEXREG_MI1] );
+ OUT_RING( code[I810_TEXREG_MI2] );
+ OUT_RING( code[I810_TEXREG_MI3] );
+
+ for ( i = 4 ; i < I810_TEX_SETUP_SIZE ; i++ ) {
+ tmp = code[i];
+
+ if ((tmp & (7<<29)) == (3<<29) &&
+ (tmp & (0x1f<<24)) < (0x1d<<24))
+ {
+ OUT_RING( tmp );
+ j++;
+ }
+ }
+
+ if (j & 1)
+ OUT_RING( 0 );
+
+ ADVANCE_LP_RING();
+}
+
+
+/* Need to do some additional checking when setting the dest buffer.
+ */
+static void i810EmitDestVerified( drm_device_t *dev,
+ volatile unsigned int *code )
+{
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ unsigned int tmp;
+ RING_LOCALS;
+
+ BEGIN_LP_RING( I810_DEST_SETUP_SIZE + 2 );
+
+ tmp = code[I810_DESTREG_DI1];
+ if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) {
+ OUT_RING( CMD_OP_DESTBUFFER_INFO );
+ OUT_RING( tmp );
+ } else
+ DRM_DEBUG("bad di1 %x (allow %x or %x)\n",
+ tmp, dev_priv->front_di1, dev_priv->back_di1);
+
+ /* invarient:
+ */
+ OUT_RING( CMD_OP_Z_BUFFER_INFO );
+ OUT_RING( dev_priv->zi1 );
+
+ OUT_RING( GFX_OP_DESTBUFFER_VARS );
+ OUT_RING( code[I810_DESTREG_DV1] );
+
+ OUT_RING( GFX_OP_DRAWRECT_INFO );
+ OUT_RING( code[I810_DESTREG_DR1] );
+ OUT_RING( code[I810_DESTREG_DR2] );
+ OUT_RING( code[I810_DESTREG_DR3] );
+ OUT_RING( code[I810_DESTREG_DR4] );
+ OUT_RING( 0 );
+
+ ADVANCE_LP_RING();
+}
+
+
+
+static void i810EmitState( drm_device_t *dev )
{
- drm_i810_private_t *dev_priv = dev->dev_private;
- drm_i810_buf_priv_t *buf_priv = buf->dev_private;
- unsigned long address = (unsigned long)buf->bus_address;
- unsigned long start = address - dev->agp->base;
- RING_LOCALS;
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ unsigned int dirty = sarea_priv->dirty;
- dev_priv->counter++;
- DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter);
- DRM_DEBUG( "i810_dma_dispatch\n");
- DRM_DEBUG( "start : 0x%lx\n", start);
- DRM_DEBUG( "used : 0x%x\n", used);
- DRM_DEBUG( "start + used - 4 : 0x%lx\n", start + used - 4);
- i810_kernel_lost_context(dev);
+ if (dirty & I810_UPLOAD_BUFFERS) {
+ i810EmitDestVerified( dev, sarea_priv->BufferState );
+ sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS;
+ }
- BEGIN_LP_RING(10);
- OUT_RING( CMD_OP_BATCH_BUFFER );
- OUT_RING( start | BB1_PROTECTED );
- OUT_RING( start + used - 4 );
- OUT_RING( CMD_STORE_DWORD_IDX );
- OUT_RING( 20 );
- OUT_RING( dev_priv->counter );
- OUT_RING( CMD_STORE_DWORD_IDX );
- OUT_RING( buf_priv->my_use_idx );
- OUT_RING( I810_BUF_FREE );
- OUT_RING( CMD_REPORT_HEAD );
- ADVANCE_LP_RING();
+ if (dirty & I810_UPLOAD_CTX) {
+ i810EmitContextVerified( dev, sarea_priv->ContextState );
+ sarea_priv->dirty &= ~I810_UPLOAD_CTX;
+ }
+
+ if (dirty & I810_UPLOAD_TEX0) {
+ i810EmitTexVerified( dev, sarea_priv->TexState[0] );
+ sarea_priv->dirty &= ~I810_UPLOAD_TEX0;
+ }
+
+ if (dirty & I810_UPLOAD_TEX1) {
+ i810EmitTexVerified( dev, sarea_priv->TexState[1] );
+ sarea_priv->dirty &= ~I810_UPLOAD_TEX1;
+ }
}
+
+
+/* need to verify
+ */
+static void i810_dma_dispatch_clear( drm_device_t *dev, int flags,
+ unsigned int clear_color,
+ unsigned int clear_zval )
+{
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ int nbox = sarea_priv->nbox;
+ drm_clip_rect_t *pbox = sarea_priv->boxes;
+ int pitch = dev_priv->pitch;
+ int cpp = 2;
+ int i;
+ RING_LOCALS;
+
+ i810_kernel_lost_context(dev);
+
+ if (nbox > I810_NR_SAREA_CLIPRECTS)
+ nbox = I810_NR_SAREA_CLIPRECTS;
+
+ for (i = 0 ; i < nbox ; i++, pbox++) {
+ unsigned int x = pbox->x1;
+ unsigned int y = pbox->y1;
+ unsigned int width = (pbox->x2 - x) * cpp;
+ unsigned int height = pbox->y2 - y;
+ unsigned int start = y * pitch + x * cpp;
+
+ if (pbox->x1 > pbox->x2 ||
+ pbox->y1 > pbox->y2 ||
+ pbox->x2 > dev_priv->w ||
+ pbox->y2 > dev_priv->h)
+ continue;
+
+ if ( flags & I810_FRONT ) {
+ DRM_DEBUG("clear front\n");
+ BEGIN_LP_RING( 6 );
+ OUT_RING( BR00_BITBLT_CLIENT |
+ BR00_OP_COLOR_BLT | 0x3 );
+ OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch );
+ OUT_RING( (height << 16) | width );
+ OUT_RING( start );
+ OUT_RING( clear_color );
+ OUT_RING( 0 );
+ ADVANCE_LP_RING();
+ }
+
+ if ( flags & I810_BACK ) {
+ DRM_DEBUG("clear back\n");
+ BEGIN_LP_RING( 6 );
+ OUT_RING( BR00_BITBLT_CLIENT |
+ BR00_OP_COLOR_BLT | 0x3 );
+ OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch );
+ OUT_RING( (height << 16) | width );
+ OUT_RING( dev_priv->back_offset + start );
+ OUT_RING( clear_color );
+ OUT_RING( 0 );
+ ADVANCE_LP_RING();
+ }
+
+ if ( flags & I810_DEPTH ) {
+ DRM_DEBUG("clear depth\n");
+ BEGIN_LP_RING( 6 );
+ OUT_RING( BR00_BITBLT_CLIENT |
+ BR00_OP_COLOR_BLT | 0x3 );
+ OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch );
+ OUT_RING( (height << 16) | width );
+ OUT_RING( dev_priv->depth_offset + start );
+ OUT_RING( clear_zval );
+ OUT_RING( 0 );
+ ADVANCE_LP_RING();
+ }
+ }
+}
+
+static void i810_dma_dispatch_swap( drm_device_t *dev )
+{
+ drm_i810_private_t *dev_priv = dev->dev_private;
+ drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ int nbox = sarea_priv->nbox;
+ drm_clip_rect_t *pbox = sarea_priv->boxes;
+ int pitch = dev_priv->pitch;
+ int cpp = 2;
+ int ofs = dev_priv->back_offset;
+ int i;
+ RING_LOCALS;
+
+ DRM_DEBUG("swapbuffers\n");
+
+ i810_kernel_lost_context(dev);
+
+ if (nbox > I810_NR_SAREA_CLIPRECTS)
+ nbox = I810_NR_SAREA_CLIPRECTS;
+
+ for (i = 0 ; i < nbox; i++, pbox++)
+ {
+ unsigned int w = pbox->x2 - pbox->x1;
+ unsigned int h = pbox->y2 - pbox->y1;
+ unsigned int dst = pbox->x1*cpp + pbox->y1*pitch;
+ unsigned int start = ofs + dst;
+
+ if (pbox->x1 > pbox->x2 ||
+ pbox->y1 > pbox->y2 ||
+ pbox->x2 > dev_priv->w ||
+ pbox->y2 > dev_priv->h)
+ continue;
+
+ DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n",
+ pbox[i].x1, pbox[i].y1,
+ pbox[i].x2, pbox[i].y2);
+
+ BEGIN_LP_RING( 6 );
+ OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 );
+ OUT_RING( pitch | (0xCC << 16));
+ OUT_RING( (h << 16) | (w * cpp));
+ OUT_RING( dst );
+ OUT_RING( pitch );
+ OUT_RING( start );
+ ADVANCE_LP_RING();
+ }
+}
+
+
static void i810_dma_dispatch_vertex(drm_device_t *dev,
drm_buf_t *buf,
int discard,
@@ -408,14 +766,29 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
int nbox = sarea_priv->nbox;
unsigned long address = (unsigned long)buf->bus_address;
unsigned long start = address - dev->agp->base;
- int i = 0;
+ int i = 0, u;
RING_LOCALS;
-
+ i810_kernel_lost_context(dev);
+
if (nbox > I810_NR_SAREA_CLIPRECTS)
nbox = I810_NR_SAREA_CLIPRECTS;
-
- DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n",
+
+ if (discard) {
+ u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
+ I810_BUF_HARDWARE);
+ if(u != I810_BUF_CLIENT) {
+ DRM_DEBUG("xxxx 2\n");
+ }
+ }
+
+ if (used > 4*1024)
+ used = 0;
+
+ if (sarea_priv->dirty)
+ i810EmitState( dev );
+
+ DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n",
address, used, nbox);
dev_priv->counter++;
@@ -424,8 +797,20 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
DRM_DEBUG( "start : %lx\n", start);
DRM_DEBUG( "used : %d\n", used);
DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4);
- i810_kernel_lost_context(dev);
+ if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
+ *(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE |
+ sarea_priv->vertex_prim |
+ ((used/4)-2));
+
+ if (used & 4) {
+ *(u32 *)((u32)buf_priv->virtual + used) = 0;
+ used += 4;
+ }
+
+ i810_unmap_buffer(buf);
+ }
+
if (used) {
do {
if (i < nbox) {
@@ -433,7 +818,7 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR |
SC_ENABLE );
OUT_RING( GFX_OP_SCISSOR_INFO );
- OUT_RING( box[i].x1 | (box[i].y1 << 16) );
+ OUT_RING( box[i].x1 | (box[i].y1<<16) );
OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) );
ADVANCE_LP_RING();
}
@@ -478,7 +863,9 @@ static void i810_dma_service(int irq, void *device, struct pt_regs *regs)
temp = temp & ~(0x6000);
if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R,
temp); /* Clear all interrupts */
-
+ else
+ return;
+
queue_task(&dev->tq, &tq_immediate);
mark_bh(IMMEDIATE_BH);
}
@@ -538,7 +925,7 @@ int i810_irq_install(drm_device_t *dev, int irq)
/* Install handler */
if ((retcode = request_irq(dev->irq,
i810_dma_service,
- 0,
+ SA_SHIRQ,
dev->devname,
dev))) {
down(&dev->struct_sem);
@@ -559,6 +946,9 @@ int i810_irq_uninstall(drm_device_t *dev)
int irq;
u16 temp;
+
+/* return 0; */
+
down(&dev->struct_sem);
irq = dev->irq;
dev->irq = 0;
@@ -617,10 +1007,15 @@ static inline void i810_dma_emit_flush(drm_device_t *dev)
RING_LOCALS;
i810_kernel_lost_context(dev);
+
BEGIN_LP_RING(2);
OUT_RING( CMD_REPORT_HEAD );
- OUT_RING( GFX_OP_USER_INTERRUPT );
+ OUT_RING( GFX_OP_USER_INTERRUPT );
ADVANCE_LP_RING();
+
+/* i810_wait_ring( dev, dev_priv->ring.Size - 8 ); */
+/* atomic_set(&dev_priv->flush_done, 1); */
+/* wake_up_interruptible(&dev_priv->flush_queue); */
}
static inline void i810_dma_quiescent_emit(drm_device_t *dev)
@@ -629,13 +1024,17 @@ static inline void i810_dma_quiescent_emit(drm_device_t *dev)
RING_LOCALS;
i810_kernel_lost_context(dev);
- BEGIN_LP_RING(4);
+ BEGIN_LP_RING(4);
OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
OUT_RING( CMD_REPORT_HEAD );
- OUT_RING( GFX_OP_USER_INTERRUPT );
- OUT_RING( 0 );
+ OUT_RING( 0 );
+ OUT_RING( GFX_OP_USER_INTERRUPT );
ADVANCE_LP_RING();
+
+/* i810_wait_ring( dev, dev_priv->ring.Size - 8 ); */
+/* atomic_set(&dev_priv->flush_done, 1); */
+/* wake_up_interruptible(&dev_priv->flush_queue); */
}
static void i810_dma_quiescent(drm_device_t *dev)
@@ -675,8 +1074,9 @@ static int i810_flush_queue(drm_device_t *dev)
{
DECLARE_WAITQUEUE(entry, current);
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+ drm_device_dma_t *dma = dev->dma;
unsigned long end;
- int ret = 0;
+ int i, ret = 0;
if(dev_priv == NULL) {
return 0;
@@ -701,7 +1101,21 @@ static int i810_flush_queue(drm_device_t *dev)
current->state = TASK_RUNNING;
remove_wait_queue(&dev_priv->flush_queue, &entry);
-
+
+
+ for (i = 0; i < dma->buf_count; i++) {
+ drm_buf_t *buf = dma->buflist[ i ];
+ drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+
+ int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE,
+ I810_BUF_FREE);
+
+ if (used == I810_BUF_HARDWARE)
+ DRM_DEBUG("reclaimed from HARDWARE\n");
+ if (used == I810_BUF_CLIENT)
+ DRM_DEBUG("still on client HARDWARE\n");
+ }
+
return ret;
}
@@ -712,20 +1126,23 @@ void i810_reclaim_buffers(drm_device_t *dev, pid_t pid)
int i;
if (!dma) return;
- if(dev->dev_private == NULL) return;
- if(dma->buflist == NULL) return;
+ if (!dev->dev_private) return;
+ if (!dma->buflist) return;
+
i810_flush_queue(dev);
for (i = 0; i < dma->buf_count; i++) {
drm_buf_t *buf = dma->buflist[ i ];
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
- /* Only buffers that need to get reclaimed ever
- * get set to free
- */
if (buf->pid == pid && buf_priv) {
- cmpxchg(buf_priv->in_use,
- I810_BUF_USED, I810_BUF_FREE);
+ int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
+ I810_BUF_FREE);
+
+ if (used == I810_BUF_CLIENT)
+ DRM_DEBUG("reclaimed from client\n");
+ if(buf_priv->currently_mapped == I810_BUF_MAPPED)
+ buf_priv->currently_mapped = I810_BUF_UNMAPPED;
}
}
}
@@ -759,19 +1176,6 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
*/
if (!ret) {
-#if 0
- if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
- != lock.context) {
- long j = jiffies - dev->lock.lock_time;
-
- if (j > 0 && j <= DRM_LOCK_SLICE) {
- /* Can't take lock if we just had it and
- there is contention. */
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(j);
- }
- }
-#endif
add_wait_queue(&dev->lock.lock_queue, &entry);
for (;;) {
if (!dev->lock.hw_lock) {
@@ -828,90 +1232,80 @@ int i810_flush_ioctl(struct inode *inode, struct file *filp,
return 0;
}
-static int i810DmaGeneral(drm_device_t *dev, drm_i810_general_t *args)
-{
- drm_device_dma_t *dma = dev->dma;
- drm_buf_t *buf = dma->buflist[ args->idx ];
-
- if (!args->used) {
- i810_freelist_put(dev, buf);
- } else {
- i810_dma_dispatch_general( dev, buf, args->used );
- atomic_add(args->used, &dma->total_bytes);
- atomic_inc(&dma->total_dmas);
- }
- return 0;
-}
-static int i810DmaVertex(drm_device_t *dev, drm_i810_vertex_t *args)
-{
- drm_device_dma_t *dma = dev->dma;
- drm_buf_t *buf = dma->buflist[ args->idx ];
- i810_dma_dispatch_vertex( dev, buf, args->discard, args->used );
- atomic_add(args->used, &dma->total_bytes);
- atomic_inc(&dma->total_dmas);
- return 0;
-}
-
-int i810_dma_general(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int i810_dma_vertex(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
- drm_i810_general_t general;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+ drm_device_dma_t *dma = dev->dma;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
u32 *hw_status = (u32 *)dev_priv->hw_status_page;
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
dev_priv->sarea_priv;
+ drm_i810_vertex_t vertex;
- int retcode = 0;
-
- copy_from_user_ret(&general, (drm_i810_general_t *)arg, sizeof(general),
+ copy_from_user_ret(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex),
-EFAULT);
- DRM_DEBUG("i810 dma general idx %d used %d\n",
- general.idx, general.used);
-
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
- DRM_ERROR("i810_dma_general called without lock held\n");
+ DRM_ERROR("i810_dma_vertex called without lock held\n");
return -EINVAL;
}
- retcode = i810DmaGeneral(dev, &general);
+ DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",
+ vertex.idx, vertex.used, vertex.discard);
+
+ i810_dma_dispatch_vertex( dev,
+ dma->buflist[ vertex.idx ],
+ vertex.discard, vertex.used );
+
+ atomic_add(vertex.used, &dma->total_bytes);
+ atomic_inc(&dma->total_dmas);
sarea_priv->last_enqueue = dev_priv->counter-1;
sarea_priv->last_dispatch = (int) hw_status[5];
- return retcode;
+ return 0;
}
-int i810_dma_vertex(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+
+
+int i810_clear_bufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
- u32 *hw_status = (u32 *)dev_priv->hw_status_page;
- drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
- dev_priv->sarea_priv;
- drm_i810_vertex_t vertex;
- int retcode = 0;
+ drm_i810_clear_t clear;
- copy_from_user_ret(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex),
+ copy_from_user_ret(&clear, (drm_i810_clear_t *)arg, sizeof(clear),
-EFAULT);
+
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
- DRM_ERROR("i810_dma_vertex called without lock held\n");
+ DRM_ERROR("i810_clear_bufs called without lock held\n");
return -EINVAL;
}
- DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",
- vertex.idx, vertex.used, vertex.discard);
+ i810_dma_dispatch_clear( dev, clear.flags,
+ clear.clear_color,
+ clear.clear_depth );
+ return 0;
+}
- retcode = i810DmaVertex(dev, &vertex);
- sarea_priv->last_enqueue = dev_priv->counter-1;
- sarea_priv->last_dispatch = (int) hw_status[5];
+int i810_swap_bufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
- return retcode;
+ DRM_DEBUG("i810_swap_bufs\n");
+ if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("i810_swap_buf called without lock held\n");
+ return -EINVAL;
+ }
+
+ i810_dma_dispatch_swap( dev );
+ return 0;
}
int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd,
@@ -928,53 +1322,32 @@ int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd,
return 0;
}
-int i810_dma(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
- drm_device_dma_t *dma = dev->dma;
int retcode = 0;
- drm_dma_t d;
+ drm_i810_dma_t d;
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
u32 *hw_status = (u32 *)dev_priv->hw_status_page;
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
dev_priv->sarea_priv;
-
- copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT);
- DRM_DEBUG("%d %d: %d send, %d req\n",
- current->pid, d.context, d.send_count, d.request_count);
+ DRM_DEBUG("getbuf\n");
+ copy_from_user_ret(&d, (drm_i810_dma_t *)arg, sizeof(d), -EFAULT);
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
DRM_ERROR("i810_dma called without lock held\n");
return -EINVAL;
}
-
- /* Please don't send us buffers.
- */
- if (d.send_count != 0) {
- DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
- current->pid, d.send_count);
- return -EINVAL;
- }
- /* We'll send you buffers.
- */
- if (d.request_count < 0 || d.request_count > dma->buf_count) {
- DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
- current->pid, d.request_count, dma->buf_count);
- return -EINVAL;
- }
-
- d.granted_count = 0;
+ d.granted = 0;
- if (!retcode && d.request_count) {
- retcode = i810_dma_get_buffers(dev, &d);
- }
+ retcode = i810_dma_get_buffer(dev, &d, filp);
- DRM_DEBUG("i810_dma: %d returning, granted = %d\n",
- current->pid, d.granted_count);
+ DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n",
+ current->pid, retcode, d.granted);
copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT);
sarea_priv->last_dispatch = (int) hw_status[5];
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h
new file mode 100644
index 000000000..4c8e09f6a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h
@@ -0,0 +1,188 @@
+#ifndef _I810_DRM_H_
+#define _I810_DRM_H_
+
+/* WARNING: These defines must be the same as what the Xserver uses.
+ * if you change them, you must change the defines in the Xserver.
+ */
+
+#ifndef _I810_DEFINES_
+#define _I810_DEFINES_
+
+#define I810_DMA_BUF_ORDER 12
+#define I810_DMA_BUF_SZ (1<<I810_DMA_BUF_ORDER)
+#define I810_DMA_BUF_NR 256
+#define I810_NR_SAREA_CLIPRECTS 8
+
+/* Each region is a minimum of 64k, and there are at most 64 of them.
+ */
+#define I810_NR_TEX_REGIONS 64
+#define I810_LOG_MIN_TEX_REGION_SIZE 16
+#endif
+
+#define I810_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */
+#define I810_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */
+#define I810_UPLOAD_CTX 0x4
+#define I810_UPLOAD_BUFFERS 0x8
+#define I810_UPLOAD_TEX0 0x10
+#define I810_UPLOAD_TEX1 0x20
+#define I810_UPLOAD_CLIPRECTS 0x40
+
+
+/* Indices into buf.Setup where various bits of state are mirrored per
+ * context and per buffer. These can be fired at the card as a unit,
+ * or in a piecewise fashion as required.
+ */
+
+/* Destbuffer state
+ * - backbuffer linear offset and pitch -- invarient in the current dri
+ * - zbuffer linear offset and pitch -- also invarient
+ * - drawing origin in back and depth buffers.
+ *
+ * Keep the depth/back buffer state here to acommodate private buffers
+ * in the future.
+ */
+#define I810_DESTREG_DI0 0 /* CMD_OP_DESTBUFFER_INFO (2 dwords) */
+#define I810_DESTREG_DI1 1
+#define I810_DESTREG_DV0 2 /* GFX_OP_DESTBUFFER_VARS (2 dwords) */
+#define I810_DESTREG_DV1 3
+#define I810_DESTREG_DR0 4 /* GFX_OP_DRAWRECT_INFO (4 dwords) */
+#define I810_DESTREG_DR1 5
+#define I810_DESTREG_DR2 6
+#define I810_DESTREG_DR3 7
+#define I810_DESTREG_DR4 8
+#define I810_DEST_SETUP_SIZE 10
+
+/* Context state
+ */
+#define I810_CTXREG_CF0 0 /* GFX_OP_COLOR_FACTOR */
+#define I810_CTXREG_CF1 1
+#define I810_CTXREG_ST0 2 /* GFX_OP_STIPPLE */
+#define I810_CTXREG_ST1 3
+#define I810_CTXREG_VF 4 /* GFX_OP_VERTEX_FMT */
+#define I810_CTXREG_MT 5 /* GFX_OP_MAP_TEXELS */
+#define I810_CTXREG_MC0 6 /* GFX_OP_MAP_COLOR_STAGES - stage 0 */
+#define I810_CTXREG_MC1 7 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */
+#define I810_CTXREG_MC2 8 /* GFX_OP_MAP_COLOR_STAGES - stage 2 */
+#define I810_CTXREG_MA0 9 /* GFX_OP_MAP_ALPHA_STAGES - stage 0 */
+#define I810_CTXREG_MA1 10 /* GFX_OP_MAP_ALPHA_STAGES - stage 1 */
+#define I810_CTXREG_MA2 11 /* GFX_OP_MAP_ALPHA_STAGES - stage 2 */
+#define I810_CTXREG_SDM 12 /* GFX_OP_SRC_DEST_MONO */
+#define I810_CTXREG_FOG 13 /* GFX_OP_FOG_COLOR */
+#define I810_CTXREG_B1 14 /* GFX_OP_BOOL_1 */
+#define I810_CTXREG_B2 15 /* GFX_OP_BOOL_2 */
+#define I810_CTXREG_LCS 16 /* GFX_OP_LINEWIDTH_CULL_SHADE_MODE */
+#define I810_CTXREG_PV 17 /* GFX_OP_PV_RULE -- Invarient! */
+#define I810_CTXREG_ZA 18 /* GFX_OP_ZBIAS_ALPHAFUNC */
+#define I810_CTXREG_AA 19 /* GFX_OP_ANTIALIAS */
+#define I810_CTX_SETUP_SIZE 20
+
+/* Texture state (per tex unit)
+ */
+#define I810_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (4 dwords) */
+#define I810_TEXREG_MI1 1
+#define I810_TEXREG_MI2 2
+#define I810_TEXREG_MI3 3
+#define I810_TEXREG_MF 4 /* GFX_OP_MAP_FILTER */
+#define I810_TEXREG_MLC 5 /* GFX_OP_MAP_LOD_CTL */
+#define I810_TEXREG_MLL 6 /* GFX_OP_MAP_LOD_LIMITS */
+#define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */
+#define I810_TEX_SETUP_SIZE 8
+
+#define I810_FRONT 0x1
+#define I810_BACK 0x2
+#define I810_DEPTH 0x4
+
+
+typedef struct _drm_i810_init {
+ enum {
+ I810_INIT_DMA = 0x01,
+ I810_CLEANUP_DMA = 0x02
+ } func;
+ int ring_map_idx;
+ int buffer_map_idx;
+ int sarea_priv_offset;
+ unsigned int ring_start;
+ unsigned int ring_end;
+ unsigned int ring_size;
+ unsigned int front_offset;
+ unsigned int back_offset;
+ unsigned int depth_offset;
+ unsigned int w;
+ unsigned int h;
+ unsigned int pitch;
+ unsigned int pitch_bits;
+} drm_i810_init_t;
+
+/* Warning: If you change the SAREA structure you must change the Xserver
+ * structure as well */
+
+typedef struct _drm_i810_tex_region {
+ unsigned char next, prev; /* indices to form a circular LRU */
+ unsigned char in_use; /* owned by a client, or free? */
+ int age; /* tracked by clients to update local LRU's */
+} drm_i810_tex_region_t;
+
+typedef struct _drm_i810_sarea {
+ unsigned int ContextState[I810_CTX_SETUP_SIZE];
+ unsigned int BufferState[I810_DEST_SETUP_SIZE];
+ unsigned int TexState[2][I810_TEX_SETUP_SIZE];
+ unsigned int dirty;
+
+ unsigned int nbox;
+ drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS];
+
+ /* Maintain an LRU of contiguous regions of texture space. If
+ * you think you own a region of texture memory, and it has an
+ * age different to the one you set, then you are mistaken and
+ * it has been stolen by another client. If global texAge
+ * hasn't changed, there is no need to walk the list.
+ *
+ * These regions can be used as a proxy for the fine-grained
+ * texture information of other clients - by maintaining them
+ * in the same lru which is used to age their own textures,
+ * clients have an approximate lru for the whole of global
+ * texture space, and can make informed decisions as to which
+ * areas to kick out. There is no need to choose whether to
+ * kick out your own texture or someone else's - simply eject
+ * them all in LRU order.
+ */
+
+ drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS+1];
+ /* Last elt is sentinal */
+ int texAge; /* last time texture was uploaded */
+ int last_enqueue; /* last time a buffer was enqueued */
+ int last_dispatch; /* age of the most recently dispatched buffer */
+ int last_quiescent; /* */
+ int ctxOwner; /* last context to upload state */
+
+ int vertex_prim;
+
+} drm_i810_sarea_t;
+
+typedef struct _drm_i810_clear {
+ int clear_color;
+ int clear_depth;
+ int flags;
+} drm_i810_clear_t;
+
+
+
+/* These may be placeholders if we have more cliprects than
+ * I810_NR_SAREA_CLIPRECTS. In that case, the client sets discard to
+ * false, indicating that the buffer will be dispatched again with a
+ * new set of cliprects.
+ */
+typedef struct _drm_i810_vertex {
+ int idx; /* buffer index */
+ int used; /* nr bytes in use */
+ int discard; /* client is finished with the buffer? */
+} drm_i810_vertex_t;
+
+typedef struct drm_i810_dma {
+ void *virtual;
+ int request_idx;
+ int request_size;
+ int granted;
+} drm_i810_dma_t;
+
+#endif /* _I810_DRM_H_ */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c
index eec9eb0f3..b523db902 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c
@@ -79,7 +79,6 @@ static drm_ioctl_desc_t i810_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { i810_addbufs, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { i810_markbufs, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { i810_infobufs, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { i810_mapbufs, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { i810_freebufs, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { i810_addctx, 1, 1 },
@@ -92,8 +91,6 @@ static drm_ioctl_desc_t i810_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { i810_dma, 1, 0 },
-
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { i810_lock, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { i810_unlock, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 },
@@ -106,11 +103,14 @@ static drm_ioctl_desc_t i810_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
+
[DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)] = { i810_dma_init, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_I810_DMA)] = { i810_dma_general,1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)] = { i810_clear_bufs, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)] = { i810_flush_ioctl,1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)] = { i810_swap_bufs, 1, 0 },
};
#define I810_IOCTL_COUNT DRM_ARRAY_SIZE(i810_ioctls)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h
index 690710c83..c387bf727 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h
@@ -32,6 +32,16 @@
#ifndef _I810_DRV_H_
#define _I810_DRV_H_
+typedef struct drm_i810_buf_priv {
+ u32 *in_use;
+ int my_use_idx;
+ int currently_mapped;
+ void *virtual;
+ void *kernel_virtual;
+ int map_count;
+ struct vm_area_struct *vma;
+} drm_i810_buf_priv_t;
+
typedef struct _drm_i810_ring_buffer{
int tail_mask;
unsigned long Start;
@@ -55,6 +65,15 @@ typedef struct drm_i810_private {
atomic_t flush_done;
wait_queue_head_t flush_queue; /* Processes waiting until flush */
+ drm_buf_t *mmap_buffer;
+
+
+ u32 front_di1, back_di1, zi1;
+
+ int back_offset;
+ int depth_offset;
+ int w, h;
+ int pitch;
} drm_i810_private_t;
/* i810_drv.c */
@@ -71,8 +90,8 @@ extern int i810_unlock(struct inode *inode, struct file *filp,
/* i810_dma.c */
extern int i810_dma_schedule(drm_device_t *dev, int locked);
-extern int i810_dma(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+extern int i810_getbuf(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
extern int i810_irq_install(drm_device_t *dev, int irq);
extern int i810_irq_uninstall(drm_device_t *dev);
extern int i810_control(struct inode *inode, struct file *filp,
@@ -86,6 +105,7 @@ extern int i810_flush_ioctl(struct inode *inode, struct file *filp,
extern void i810_reclaim_buffers(drm_device_t *dev, pid_t pid);
extern int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg);
+extern int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma);
/* i810_bufs.c */
@@ -97,8 +117,6 @@ extern int i810_markbufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int i810_freebufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int i810_mapbufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
extern int i810_addmap(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
@@ -121,32 +139,17 @@ extern int i810_rmctx(struct inode *inode, struct file *filp,
extern int i810_context_switch(drm_device_t *dev, int old, int new);
extern int i810_context_switch_complete(drm_device_t *dev, int new);
-
-
-
-/* Copy the outstanding cliprects for every I810_DMA_VERTEX buffer.
- * This can be fixed by emitting directly to the ringbuffer in the
- * 'vertex_dma' ioctl.
-*/
-typedef struct {
- u32 *in_use;
- int my_use_idx;
-} drm_i810_buf_priv_t;
-
-
-#define I810_DMA_GENERAL 0
-#define I810_DMA_VERTEX 1
-#define I810_DMA_DISCARD 2 /* not used */
-
#define I810_VERBOSE 0
int i810_dma_vertex(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-int i810_dma_general(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+int i810_swap_bufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+int i810_clear_bufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
@@ -200,5 +203,22 @@ int i810_dma_general(struct inode *inode, struct file *filp,
#define SCI_YMAX_MASK (0xffff<<16)
#define SCI_XMAX_MASK (0xffff<<0)
+#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
+#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
+#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x2)
+#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
+#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
+#define GFX_OP_PRIMITIVE ((0x3<<29)|(0x1f<<24))
+
+#define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23))
+#define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23))
+
+#define BR00_BITBLT_CLIENT 0x40000000
+#define BR00_OP_COLOR_BLT 0x10000000
+#define BR00_OP_SRC_COPY_BLT 0x10C00000
+#define BR13_SOLID_PATTERN 0x80000000
+
+
+
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c
index b03544bc2..25e3622ca 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c
@@ -52,6 +52,7 @@ static unsigned long mga_alloc_page(drm_device_t *dev)
{
unsigned long address;
+ DRM_DEBUG("%s\n", __FUNCTION__);
address = __get_free_page(GFP_KERNEL);
if(address == 0UL) {
return 0;
@@ -64,6 +65,8 @@ static unsigned long mga_alloc_page(drm_device_t *dev)
static void mga_free_page(drm_device_t *dev, unsigned long page)
{
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
if(page == 0UL) {
return;
}
@@ -79,9 +82,11 @@ static void mga_delay(void)
return;
}
-static void mga_flush_write_combine(void)
+void mga_flush_write_combine(void)
{
int xchangeDummy;
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
__asm__ volatile(" push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy));
__asm__ volatile(" push %%eax ; push %%ebx ; push %%ecx ; push %%edx ;"
" movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;"
@@ -93,18 +98,6 @@ static void mga_flush_write_combine(void)
#define MGA_BUF_USED 0xffffffff
#define MGA_BUF_FREE 0
-static void mga_freelist_debug(drm_mga_freelist_t *item)
-{
- if(item->buf != NULL) {
- DRM_DEBUG("buf index : %d\n", item->buf->idx);
- } else {
- DRM_DEBUG("Freelist head\n");
- }
- DRM_DEBUG("item->age : %x\n", item->age);
- DRM_DEBUG("item->next : %p\n", item->next);
- DRM_DEBUG("item->prev : %p\n", item->prev);
-}
-
static int mga_freelist_init(drm_device_t *dev)
{
drm_device_dma_t *dma = dev->dma;
@@ -113,7 +106,9 @@ static int mga_freelist_init(drm_device_t *dev)
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_freelist_t *item;
int i;
-
+
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
dev_priv->head = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
if(dev_priv->head == NULL) return -ENOMEM;
memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t));
@@ -135,19 +130,10 @@ static int mga_freelist_init(drm_device_t *dev)
item->buf = buf;
buf_priv->my_freelist = item;
buf_priv->discard = 0;
+ buf_priv->dispatched = 0;
dev_priv->head->next = item;
}
- item = dev_priv->head;
- while(item) {
- mga_freelist_debug(item);
- item = item->next;
- }
- DRM_DEBUG("Head\n");
- mga_freelist_debug(dev_priv->head);
- DRM_DEBUG("Tail\n");
- mga_freelist_debug(dev_priv->tail);
-
return 0;
}
@@ -157,6 +143,8 @@ static void mga_freelist_cleanup(drm_device_t *dev)
drm_mga_freelist_t *item;
drm_mga_freelist_t *prev;
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
item = dev_priv->head;
while(item) {
prev = item;
@@ -173,14 +161,14 @@ static inline void mga_dma_quiescent(drm_device_t *dev)
drm_device_dma_t *dma = dev->dma;
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- __volatile__ unsigned int *status =
- (__volatile__ unsigned int *)dev_priv->status_page;
unsigned long end;
int i;
+ DRM_DEBUG("%s\n", __FUNCTION__);
end = jiffies + (HZ*3);
while(1) {
- if(!test_and_set_bit(0, &dev_priv->dispatch_lock)) {
+ if(!test_and_set_bit(MGA_IN_DISPATCH,
+ &dev_priv->dispatch_status)) {
break;
}
if((signed)(end - jiffies) <= 0) {
@@ -204,51 +192,25 @@ static inline void mga_dma_quiescent(drm_device_t *dev)
}
for (i = 0 ; i < 2000 ; i++) mga_delay();
}
- DRM_DEBUG("status[1] : %x last_sync_tag : %x\n", status[1],
- dev_priv->last_sync_tag);
sarea_priv->dirty |= MGA_DMA_FLUSH;
out_status:
- clear_bit(0, &dev_priv->dispatch_lock);
+ clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
out_nolock:
}
-#define FREELIST_INITIAL (MGA_DMA_BUF_NR * 2)
-#define FREELIST_COMPARE(age) ((age >> 2))
-
-unsigned int mga_create_sync_tag(drm_device_t *dev)
+static void mga_reset_freelist(drm_device_t *dev)
{
- drm_mga_private_t *dev_priv =
- (drm_mga_private_t *) dev->dev_private;
- unsigned int temp;
- drm_buf_t *buf;
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_t *buf;
drm_mga_buf_priv_t *buf_priv;
- drm_device_dma_t *dma = dev->dma;
- int i;
-
- dev_priv->sync_tag++;
-
- if(dev_priv->sync_tag < FREELIST_INITIAL) {
- dev_priv->sync_tag = FREELIST_INITIAL;
- }
- if(dev_priv->sync_tag > 0x3fffffff) {
- mga_flush_queue(dev);
- mga_dma_quiescent(dev);
-
- for (i = 0; i < dma->buf_count; i++) {
- buf = dma->buflist[ i ];
- buf_priv = buf->dev_private;
- buf_priv->my_freelist->age = MGA_BUF_FREE;
- }
-
- dev_priv->sync_tag = FREELIST_INITIAL;
- }
- temp = dev_priv->sync_tag << 2;
-
- dev_priv->sarea_priv->last_enqueue = temp;
+ int i;
- DRM_DEBUG("sync_tag : %x\n", temp);
- return temp;
+ for (i = 0; i < dma->buf_count; i++) {
+ buf = dma->buflist[ i ];
+ buf_priv = buf->dev_private;
+ buf_priv->my_freelist->age = MGA_BUF_FREE;
+ }
}
/* Least recently used :
@@ -257,23 +219,52 @@ unsigned int mga_create_sync_tag(drm_device_t *dev)
drm_buf_t *mga_freelist_get(drm_device_t *dev)
{
+ DECLARE_WAITQUEUE(entry, current);
drm_mga_private_t *dev_priv =
(drm_mga_private_t *) dev->dev_private;
- __volatile__ unsigned int *status =
- (__volatile__ unsigned int *)dev_priv->status_page;
drm_mga_freelist_t *prev;
drm_mga_freelist_t *next;
+ static int failed = 0;
+
+ DRM_DEBUG("%s : tail->age : %d last_prim_age : %d\n", __FUNCTION__,
+ dev_priv->tail->age, dev_priv->last_prim_age);
- if((dev_priv->tail->age >> 2) <= FREELIST_COMPARE(status[1])) {
+ if(failed >= 1000 && dev_priv->tail->age >= dev_priv->last_prim_age) {
+ DRM_DEBUG("I'm waiting on the freelist!!! %d\n",
+ dev_priv->last_prim_age);
+ set_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
+ current->state = TASK_INTERRUPTIBLE;
+ add_wait_queue(&dev_priv->buf_queue, &entry);
+ for (;;) {
+ mga_dma_schedule(dev, 0);
+ if(!test_bit(MGA_IN_GETBUF,
+ &dev_priv->dispatch_status))
+ break;
+ atomic_inc(&dev->total_sleeps);
+ schedule();
+ if (signal_pending(current)) {
+ clear_bit(MGA_IN_GETBUF,
+ &dev_priv->dispatch_status);
+ goto failed_getbuf;
+ }
+ }
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&dev_priv->buf_queue, &entry);
+ }
+
+ if(dev_priv->tail->age < dev_priv->last_prim_age) {
prev = dev_priv->tail->prev;
next = dev_priv->tail;
prev->next = NULL;
next->prev = next->next = NULL;
dev_priv->tail = prev;
next->age = MGA_BUF_USED;
+ failed = 0;
return next->buf;
- }
+ }
+failed_getbuf:
+ failed++;
return NULL;
}
@@ -286,6 +277,8 @@ int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf)
drm_mga_freelist_t *head;
drm_mga_freelist_t *next;
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
if(buf_priv->my_freelist->age == MGA_BUF_USED) {
/* Discarded buffer, put it on the tail */
next = buf_priv->my_freelist;
@@ -312,32 +305,6 @@ int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf)
return 0;
}
-static void mga_print_all_primary(drm_device_t *dev)
-{
- drm_mga_private_t *dev_priv = dev->dev_private;
- drm_mga_prim_buf_t *prim;
- int i;
-
- DRM_DEBUG("Full list of primarys\n");
- for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) {
- prim = dev_priv->prim_bufs[i];
- DRM_DEBUG("index : %d num_dwords : %d "
- "max_dwords : %d phy_head : %x\n",
- prim->idx, prim->num_dwords,
- prim->max_dwords, prim->phys_head);
- DRM_DEBUG("sec_used : %d swap_pending : %x "
- "in_use : %x force_fire : %d\n",
- prim->sec_used, prim->swap_pending,
- prim->in_use, atomic_read(&prim->force_fire));
- DRM_DEBUG("needs_overflow : %d\n",
- atomic_read(&prim->needs_overflow));
- }
-
- DRM_DEBUG("current_idx : %d, next_idx : %d, last_idx : %d\n",
- dev_priv->next_prim->idx, dev_priv->last_prim->idx,
- dev_priv->current_prim->idx);
-}
-
static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
{
drm_mga_private_t *dev_priv = dev->dev_private;
@@ -345,10 +312,9 @@ static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
int i, temp, size_of_buf;
int offset = init->reserved_map_agpstart;
- DRM_DEBUG("mga_init_primary_bufs\n");
+ DRM_DEBUG("%s\n", __FUNCTION__);
dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) /
PAGE_SIZE) * PAGE_SIZE;
- DRM_DEBUG("primary_size\n");
size_of_buf = dev_priv->primary_size / MGA_NUM_PRIM_BUFS;
dev_priv->warp_ucode_size = init->warp_ucode_size;
dev_priv->prim_bufs = drm_alloc(sizeof(drm_mga_prim_buf_t *) *
@@ -358,18 +324,12 @@ static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
DRM_ERROR("Unable to allocate memory for prim_buf\n");
return -ENOMEM;
}
- DRM_DEBUG("memset\n");
memset(dev_priv->prim_bufs,
0, sizeof(drm_mga_prim_buf_t *) * (MGA_NUM_PRIM_BUFS + 1));
temp = init->warp_ucode_size + dev_priv->primary_size;
temp = ((temp + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
- DRM_DEBUG("temp : %x\n", temp);
- DRM_DEBUG("dev->agp->base: %lx\n", dev->agp->base);
- DRM_DEBUG("init->reserved_map_agpstart: %x\n",
- init->reserved_map_agpstart);
- DRM_DEBUG("ioremap\n");
dev_priv->ioremap = drm_ioremap(dev->agp->base + offset,
temp);
if(dev_priv->ioremap == NULL) {
@@ -379,11 +339,9 @@ static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
init_waitqueue_head(&dev_priv->wait_queue);
for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) {
- DRM_DEBUG("For loop\n");
prim_buffer = drm_alloc(sizeof(drm_mga_prim_buf_t),
DRM_MEM_DRIVER);
if(prim_buffer == NULL) return -ENOMEM;
- DRM_DEBUG("memset\n");
memset(prim_buffer, 0, sizeof(drm_mga_prim_buf_t));
prim_buffer->phys_head = offset + dev->agp->base;
prim_buffer->current_dma_ptr =
@@ -396,17 +354,18 @@ static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
prim_buffer->max_dwords -= 5; /* Leave room for the softrap */
prim_buffer->sec_used = 0;
prim_buffer->idx = i;
+ prim_buffer->prim_age = i + 1;
offset = offset + size_of_buf;
dev_priv->prim_bufs[i] = prim_buffer;
- DRM_DEBUG("Looping\n");
}
dev_priv->current_prim_idx = 0;
dev_priv->next_prim =
dev_priv->last_prim =
dev_priv->current_prim =
dev_priv->prim_bufs[0];
- set_bit(0, &dev_priv->current_prim->in_use);
- DRM_DEBUG("init done\n");
+ dev_priv->next_prim_age = 2;
+ dev_priv->last_prim_age = 1;
+ set_bit(MGA_BUF_IN_USE, &dev_priv->current_prim->buffer_status);
return 0;
}
@@ -420,9 +379,8 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim)
int i;
int next_idx;
PRIMLOCALS;
-
- DRM_DEBUG("mga_fire_primary\n");
- dev_priv->last_sync_tag = mga_create_sync_tag(dev);
+
+ DRM_DEBUG("%s\n", __FUNCTION__);
dev_priv->last_prim = prim;
/* We never check for overflow, b/c there is always room */
@@ -433,7 +391,7 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim)
}
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
+ PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG( MGAREG_SOFTRAP, 0);
PRIMFINISH(prim);
@@ -468,13 +426,13 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim)
for (i = 0 ; i < 4096 ; i++) mga_delay();
}
}
-
+
mga_flush_write_combine();
atomic_inc(&dev_priv->pending_bufs);
- atomic_inc(&dma->total_lost);
MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
prim->num_dwords = 0;
+ sarea_priv->last_enqueue = prim->prim_age;
next_idx = prim->idx + 1;
if(next_idx >= MGA_NUM_PRIM_BUFS)
@@ -486,11 +444,10 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim)
out_prim_wait:
prim->num_dwords = 0;
prim->sec_used = 0;
- clear_bit(0, &prim->in_use);
+ clear_bit(MGA_BUF_IN_USE, &prim->buffer_status);
wake_up_interruptible(&dev_priv->wait_queue);
- clear_bit(0, &prim->swap_pending);
- clear_bit(0, &dev_priv->dispatch_lock);
- atomic_dec(&dev_priv->pending_bufs);
+ clear_bit(MGA_BUF_SWAP_PENDING, &prim->buffer_status);
+ clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
}
int mga_advance_primary(drm_device_t *dev)
@@ -505,27 +462,28 @@ int mga_advance_primary(drm_device_t *dev)
/* This needs to reset the primary buffer if available,
* we should collect stats on how many times it bites
* it's tail */
+ DRM_DEBUG("%s\n", __FUNCTION__);
next_prim_idx = dev_priv->current_prim_idx + 1;
if(next_prim_idx >= MGA_NUM_PRIM_BUFS)
next_prim_idx = 0;
prim_buffer = dev_priv->prim_bufs[next_prim_idx];
- atomic_set(&dev_priv->in_wait, 1);
+ set_bit(MGA_IN_WAIT, &dev_priv->dispatch_status);
/* In use is cleared in interrupt handler */
- if(test_and_set_bit(0, &prim_buffer->in_use)) {
+ if(test_and_set_bit(MGA_BUF_IN_USE, &prim_buffer->buffer_status)) {
add_wait_queue(&dev_priv->wait_queue, &entry);
+ current->state = TASK_INTERRUPTIBLE;
+
for (;;) {
- current->state = TASK_INTERRUPTIBLE;
mga_dma_schedule(dev, 0);
- if(!test_and_set_bit(0, &prim_buffer->in_use)) break;
+ if(!test_and_set_bit(MGA_BUF_IN_USE,
+ &prim_buffer->buffer_status))
+ break;
atomic_inc(&dev->total_sleeps);
atomic_inc(&dma->total_missed_sched);
- mga_print_all_primary(dev);
- DRM_DEBUG("Schedule in advance\n");
- /* Three second delay */
- schedule_timeout(HZ*3);
+ schedule();
if (signal_pending(current)) {
ret = -ERESTARTSYS;
break;
@@ -535,16 +493,27 @@ int mga_advance_primary(drm_device_t *dev)
remove_wait_queue(&dev_priv->wait_queue, &entry);
if(ret) return ret;
}
- atomic_set(&dev_priv->in_wait, 0);
+ clear_bit(MGA_IN_WAIT, &dev_priv->dispatch_status);
+
/* This primary buffer is now free to use */
prim_buffer->current_dma_ptr = prim_buffer->head;
prim_buffer->num_dwords = 0;
prim_buffer->sec_used = 0;
- atomic_set(&prim_buffer->needs_overflow, 0);
+ prim_buffer->prim_age = dev_priv->next_prim_age++;
+ if(prim_buffer->prim_age == 0 || prim_buffer->prim_age == 0xffffffff) {
+ mga_flush_queue(dev);
+ mga_dma_quiescent(dev);
+ mga_reset_freelist(dev);
+ prim_buffer->prim_age = (dev_priv->next_prim_age += 2);
+ }
+
+ /* Reset all buffer status stuff */
+ clear_bit(MGA_BUF_NEEDS_OVERFLOW, &prim_buffer->buffer_status);
+ clear_bit(MGA_BUF_FORCE_FIRE, &prim_buffer->buffer_status);
+ clear_bit(MGA_BUF_SWAP_PENDING, &prim_buffer->buffer_status);
+
dev_priv->current_prim = prim_buffer;
dev_priv->current_prim_idx = next_prim_idx;
- DRM_DEBUG("Primarys at advance\n");
- mga_print_all_primary(dev);
return 0;
}
@@ -553,21 +522,29 @@ static inline int mga_decide_to_fire(drm_device_t *dev)
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_device_dma_t *dma = dev->dma;
-
- if(atomic_read(&dev_priv->next_prim->force_fire))
- {
+
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
+ if(test_bit(MGA_BUF_FORCE_FIRE, &dev_priv->next_prim->buffer_status)) {
atomic_inc(&dma->total_prio);
return 1;
}
- if (atomic_read(&dev_priv->in_flush) && dev_priv->next_prim->num_dwords)
- {
+ if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
+ dev_priv->next_prim->num_dwords) {
+ atomic_inc(&dma->total_prio);
+ return 1;
+ }
+
+ if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
+ dev_priv->next_prim->num_dwords) {
atomic_inc(&dma->total_prio);
return 1;
}
if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS - 1) {
- if(test_bit(0, &dev_priv->next_prim->swap_pending)) {
+ if(test_bit(MGA_BUF_SWAP_PENDING,
+ &dev_priv->next_prim->buffer_status)) {
atomic_inc(&dma->total_dmas);
return 1;
}
@@ -601,10 +578,11 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
return -EBUSY;
}
- DRM_DEBUG("mga_dma_schedule\n");
+ DRM_DEBUG("%s\n", __FUNCTION__);
- if(atomic_read(&dev_priv->in_flush) ||
- atomic_read(&dev_priv->in_wait)) {
+ if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) ||
+ test_bit(MGA_IN_WAIT, &dev_priv->dispatch_status) ||
+ test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)) {
locked = 1;
}
@@ -612,27 +590,25 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
!drm_lock_take(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) {
atomic_inc(&dma->total_missed_lock);
clear_bit(0, &dev->dma_flag);
+ DRM_DEBUG("Not locked\n");
return -EBUSY;
}
DRM_DEBUG("I'm locked\n");
-
- if(!test_and_set_bit(0, &dev_priv->dispatch_lock)) {
+ if(!test_and_set_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status)) {
/* Fire dma buffer */
if(mga_decide_to_fire(dev)) {
- DRM_DEBUG("mga_fire_primary\n");
DRM_DEBUG("idx :%d\n", dev_priv->next_prim->idx);
- atomic_set(&dev_priv->next_prim->force_fire, 0);
- if(dev_priv->current_prim == dev_priv->next_prim &&
- dev_priv->next_prim->num_dwords != 0) {
+ clear_bit(MGA_BUF_FORCE_FIRE,
+ &dev_priv->next_prim->buffer_status);
+ if(dev_priv->current_prim == dev_priv->next_prim) {
/* Schedule overflow for a later time */
- atomic_set(
- &dev_priv->current_prim->needs_overflow,
- 1);
+ set_bit(MGA_BUF_NEEDS_OVERFLOW,
+ &dev_priv->next_prim->buffer_status);
}
mga_fire_primary(dev, dev_priv->next_prim);
} else {
- clear_bit(0, &dev_priv->dispatch_lock);
+ clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
}
} else {
DRM_DEBUG("I can't get the dispatch lock\n");
@@ -645,17 +621,26 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
}
}
- clear_bit(0, &dev->dma_flag);
-
- if(atomic_read(&dev_priv->in_flush) == 1 &&
- dev_priv->next_prim->num_dwords == 0) {
- /* Everything is on the hardware */
- DRM_DEBUG("Primarys at Flush\n");
- mga_print_all_primary(dev);
- atomic_set(&dev_priv->in_flush, 0);
+ if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
+ dev_priv->next_prim->num_dwords == 0 &&
+ atomic_read(&dev_priv->pending_bufs) == 0) {
+ /* Everything has been processed by the hardware */
+ clear_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status);
wake_up_interruptible(&dev_priv->flush_queue);
}
+ if(test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
+ dev_priv->tail->age < dev_priv->last_prim_age) {
+ clear_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
+ DRM_DEBUG("Waking up buf queue\n");
+ wake_up_interruptible(&dev_priv->buf_queue);
+ } else if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)) {
+ DRM_DEBUG("Not waking buf_queue on %d %d\n",
+ atomic_read(&dev->total_irq),
+ dev_priv->last_prim_age);
+ }
+
+ clear_bit(0, &dev->dma_flag);
return 0;
}
@@ -664,33 +649,35 @@ static void mga_dma_service(int irq, void *device, struct pt_regs *regs)
drm_device_t *dev = (drm_device_t *)device;
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_prim_buf_t *last_prim_buffer;
- __volatile__ unsigned int *status =
- (__volatile__ unsigned int *)dev_priv->status_page;
-
+
+ DRM_DEBUG("%s\n", __FUNCTION__);
atomic_inc(&dev->total_irq);
+ if((MGA_READ(MGAREG_STATUS) & 0x00000001) != 0x00000001) return;
MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
last_prim_buffer = dev_priv->last_prim;
last_prim_buffer->num_dwords = 0;
last_prim_buffer->sec_used = 0;
- clear_bit(0, &last_prim_buffer->in_use);
+ dev_priv->sarea_priv->last_dispatch =
+ dev_priv->last_prim_age = last_prim_buffer->prim_age;
+ clear_bit(MGA_BUF_IN_USE, &last_prim_buffer->buffer_status);
wake_up_interruptible(&dev_priv->wait_queue);
- clear_bit(0, &last_prim_buffer->swap_pending);
- clear_bit(0, &dev_priv->dispatch_lock);
+ clear_bit(MGA_BUF_SWAP_PENDING, &last_prim_buffer->buffer_status);
+ clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
atomic_dec(&dev_priv->pending_bufs);
- dev_priv->sarea_priv->last_dispatch = status[1];
queue_task(&dev->tq, &tq_immediate);
mark_bh(IMMEDIATE_BH);
}
static void mga_dma_task_queue(void *device)
{
- drm_device_t *dev = (drm_device_t *) device;
-
- mga_dma_schedule(dev, 0);
+ DRM_DEBUG("%s\n", __FUNCTION__);
+ mga_dma_schedule((drm_device_t *)device, 0);
}
int mga_dma_cleanup(drm_device_t *dev)
{
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
if(dev->dev_private) {
drm_mga_private_t *dev_priv =
(drm_mga_private_t *) dev->dev_private;
@@ -739,14 +726,13 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
drm_map_t *sarea_map = NULL;
int i;
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
if(dev_priv == NULL) return -ENOMEM;
dev->dev_private = (void *) dev_priv;
- DRM_DEBUG("dev_private\n");
-
memset(dev_priv, 0, sizeof(drm_mga_private_t));
- atomic_set(&dev_priv->in_flush, 0);
if((init->reserved_map_idx >= dev->map_count) ||
(init->buffer_map_idx >= dev->map_count)) {
@@ -761,7 +747,6 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
dev_priv->sarea_priv = (drm_mga_sarea_t *)
((u8 *)sarea_map->handle +
init->sarea_priv_offset);
- DRM_DEBUG("sarea_priv\n");
/* Scale primary size to the next page */
dev_priv->chipset = init->chipset;
@@ -776,6 +761,7 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
dev_priv->mAccess = init->mAccess;
init_waitqueue_head(&dev_priv->flush_queue);
+ init_waitqueue_head(&dev_priv->buf_queue);
dev_priv->WarpPipe = -1;
DRM_DEBUG("chipset: %d ucode_size: %d backOffset: %x depthOffset: %x\n",
@@ -795,20 +781,17 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
dev_priv->WarpIndex[i].phys_addr,
dev_priv->WarpIndex[i].size);
- DRM_DEBUG("Doing init prim buffers\n");
if(mga_init_primary_bufs(dev, init) != 0) {
DRM_ERROR("Can not initialize primary buffers\n");
mga_dma_cleanup(dev);
return -ENOMEM;
}
- DRM_DEBUG("Done with init prim buffers\n");
dev_priv->real_status_page = mga_alloc_page(dev);
if(dev_priv->real_status_page == 0UL) {
mga_dma_cleanup(dev);
DRM_ERROR("Can not allocate status page\n");
return -ENOMEM;
}
- DRM_DEBUG("Status page at %lx\n", dev_priv->real_status_page);
dev_priv->status_page =
ioremap_nocache(virt_to_bus((void *)dev_priv->real_status_page),
@@ -820,38 +803,23 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
return -ENOMEM;
}
- DRM_DEBUG("Status page remapped to %p\n", dev_priv->status_page);
/* Write status page when secend or softrap occurs */
MGA_WRITE(MGAREG_PRIMPTR,
virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003);
-
- dev_priv->device = pci_find_device(0x102b, 0x0525, NULL);
- if(dev_priv->device == NULL) {
- DRM_ERROR("Could not find pci device for card\n");
- mga_dma_cleanup(dev);
- return -EINVAL;
- }
-
- DRM_DEBUG("dma initialization\n");
+
/* Private is now filled in, initialize the hardware */
{
- __volatile__ unsigned int *status =
- (unsigned int *)dev_priv->status_page;
PRIMLOCALS;
PRIMGETPTR( dev_priv );
-
- dev_priv->last_sync_tag = mga_create_sync_tag(dev);
-
+
PRIMOUTREG(MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DWGSYNC, dev_priv->last_sync_tag);
+ PRIMOUTREG(MGAREG_DWGSYNC, 0x0100);
PRIMOUTREG(MGAREG_SOFTRAP, 0);
/* Poll for the first buffer to insure that
* the status register will be correct
*/
- DRM_DEBUG("phys_head : %lx\n", (unsigned long)phys_head);
- status[1] = 0;
mga_flush_write_combine();
MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
@@ -859,9 +827,7 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) |
PDEA_pagpxfer_enable));
- while(MGA_READ(MGAREG_DWGSYNC) != dev_priv->last_sync_tag) ;
- DRM_DEBUG("status[0] after initialization : %x\n", status[0]);
- DRM_DEBUG("status[1] after initialization : %x\n", status[1]);
+ while(MGA_READ(MGAREG_DWGSYNC) != 0x0100) ;
}
if(mga_freelist_init(dev) != 0) {
@@ -869,7 +835,6 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
mga_dma_cleanup(dev);
return -ENOMEM;
}
- DRM_DEBUG("dma init was successful\n");
return 0;
}
@@ -880,6 +845,8 @@ int mga_dma_init(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
drm_mga_init_t init;
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
copy_from_user_ret(&init, (drm_mga_init_t *)arg, sizeof(init), -EFAULT);
switch(init.func) {
@@ -924,7 +891,7 @@ int mga_irq_install(drm_device_t *dev, int irq)
/* Install handler */
if ((retcode = request_irq(dev->irq,
mga_dma_service,
- 0,
+ SA_SHIRQ,
dev->devname,
dev))) {
down(&dev->struct_sem);
@@ -963,7 +930,9 @@ int mga_control(struct inode *inode, struct file *filp, unsigned int cmd,
drm_control_t ctl;
copy_from_user_ret(&ctl, (drm_control_t *)arg, sizeof(ctl), -EFAULT);
-
+
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
switch (ctl.func) {
case DRM_INST_HANDLER:
return mga_irq_install(dev, ctl.irq);
@@ -980,30 +949,33 @@ static int mga_flush_queue(drm_device_t *dev)
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
int ret = 0;
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
if(dev_priv == NULL) {
return 0;
}
if(dev_priv->next_prim->num_dwords != 0) {
- atomic_set(&dev_priv->in_flush, 1);
+ set_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status);
current->state = TASK_INTERRUPTIBLE;
add_wait_queue(&dev_priv->flush_queue, &entry);
for (;;) {
mga_dma_schedule(dev, 0);
- if (atomic_read(&dev_priv->in_flush) == 0)
+ if (!test_bit(MGA_IN_FLUSH,
+ &dev_priv->dispatch_status))
break;
atomic_inc(&dev->total_sleeps);
- DRM_DEBUG("Schedule in flush_queue\n");
- schedule_timeout(HZ*3);
+ schedule();
if (signal_pending(current)) {
ret = -EINTR; /* Can't restart */
+ clear_bit(MGA_IN_FLUSH,
+ &dev_priv->dispatch_status);
break;
}
}
current->state = TASK_RUNNING;
remove_wait_queue(&dev_priv->flush_queue, &entry);
}
- atomic_set(&dev_priv->in_flush, 0);
return ret;
}
@@ -1017,6 +989,7 @@ void mga_reclaim_buffers(drm_device_t *dev, pid_t pid)
if(dev->dev_private == NULL) return;
if(dma->buflist == NULL) return;
+ DRM_DEBUG("%s\n", __FUNCTION__);
mga_flush_queue(dev);
for (i = 0; i < dma->buf_count; i++) {
@@ -1042,6 +1015,7 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
int ret = 0;
drm_lock_t lock;
+ DRM_DEBUG("%s\n", __FUNCTION__);
copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
if (lock.context == DRM_KERNEL_CONTEXT) {
@@ -1080,7 +1054,6 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
/* Contention */
atomic_inc(&dev->total_sleeps);
current->state = TASK_INTERRUPTIBLE;
- DRM_DEBUG("Calling lock schedule\n");
schedule();
if (signal_pending(current)) {
ret = -ERESTARTSYS;
@@ -1110,11 +1083,8 @@ int mga_flush_ioctl(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
drm_lock_t lock;
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
- drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- __volatile__ unsigned int *status =
- (__volatile__ unsigned int *)dev_priv->status_page;
- int i;
-
+
+ DRM_DEBUG("%s\n", __FUNCTION__);
copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
@@ -1123,28 +1093,17 @@ int mga_flush_ioctl(struct inode *inode, struct file *filp,
}
if(lock.flags & _DRM_LOCK_FLUSH || lock.flags & _DRM_LOCK_FLUSH_ALL) {
- mga_flush_queue(dev);
-
- if((MGA_READ(MGAREG_STATUS) & 0x00030001) == 0x00020000 &&
- status[1] != dev_priv->last_sync_tag)
- {
- DRM_DEBUG("Reseting hardware status\n");
- MGA_WRITE(MGAREG_DWGSYNC, dev_priv->last_sync_tag);
-
- while(MGA_READ(MGAREG_DWGSYNC) !=
- dev_priv->last_sync_tag)
- {
- for(i = 0; i < 4096; i++) mga_delay();
- }
-
- status[1] =
- sarea_priv->last_dispatch =
- dev_priv->last_sync_tag;
- } else {
- sarea_priv->last_dispatch = status[1];
- }
+ drm_mga_prim_buf_t *temp_buf =
+ dev_priv->prim_bufs[dev_priv->current_prim_idx];
+
+ if(temp_buf && temp_buf->num_dwords) {
+ set_bit(MGA_BUF_FORCE_FIRE, &temp_buf->buffer_status);
+ mga_advance_primary(dev);
+ mga_dma_schedule(dev, 1);
+ }
}
if(lock.flags & _DRM_LOCK_QUIESCENT) {
+ mga_flush_queue(dev);
mga_dma_quiescent(dev);
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h
index 53d3590b1..e75e91a4f 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm.h
@@ -37,6 +37,7 @@
*/
#ifndef _MGA_DEFINES_
#define _MGA_DEFINES_
+
#define MGA_F 0x1 /* fog */
#define MGA_A 0x2 /* alpha */
#define MGA_S 0x4 /* specular */
@@ -61,11 +62,11 @@
#define MGA_MAX_G400_PIPES 16
#define MGA_MAX_G200_PIPES 8 /* no multitex */
-
#define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES
#define MGA_CARD_TYPE_G200 1
#define MGA_CARD_TYPE_G400 2
+
#define MGA_FRONT 0x1
#define MGA_BACK 0x2
#define MGA_DEPTH 0x4
@@ -110,19 +111,19 @@
#define MGA_UPLOAD_TEX0 0x2
#define MGA_UPLOAD_TEX1 0x4
#define MGA_UPLOAD_PIPE 0x8
-#define MGA_UPLOAD_TEX0IMAGE 0x10
-#define MGA_UPLOAD_TEX1IMAGE 0x20
+#define MGA_UPLOAD_TEX0IMAGE 0x10 /* handled client-side */
+#define MGA_UPLOAD_TEX1IMAGE 0x20 /* handled client-side */
#define MGA_UPLOAD_2D 0x40
#define MGA_WAIT_AGE 0x80 /* handled client-side */
#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */
#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock
quiescent */
-/* 64 buffers of 16k each, total 1 meg.
+/* 32 buffers of 64k each, total 2 meg.
*/
-#define MGA_DMA_BUF_ORDER 14
+#define MGA_DMA_BUF_ORDER 16
#define MGA_DMA_BUF_SZ (1<<MGA_DMA_BUF_ORDER)
-#define MGA_DMA_BUF_NR 63
+#define MGA_DMA_BUF_NR 31
/* Keep these small for testing.
*/
@@ -159,19 +160,19 @@ typedef struct drm_mga_init {
int sarea_priv_offset;
int primary_size;
int warp_ucode_size;
- int frontOffset;
- int backOffset;
- int depthOffset;
- int textureOffset;
- int textureSize;
- int agpTextureOffset;
- int agpTextureSize;
- int cpp;
- int stride;
+ unsigned int frontOffset;
+ unsigned int backOffset;
+ unsigned int depthOffset;
+ unsigned int textureOffset;
+ unsigned int textureSize;
+ unsigned int agpTextureOffset;
+ unsigned int agpTextureSize;
+ unsigned int cpp;
+ unsigned int stride;
int sgram;
int chipset;
drm_mga_warp_index_t WarpIndex[MGA_MAX_WARP_PIPES];
- int mAccess;
+ unsigned int mAccess;
} drm_mga_init_t;
/* Warning: if you change the sarea structure, you must change the Xserver
@@ -180,7 +181,7 @@ typedef struct drm_mga_init {
typedef struct _drm_mga_tex_region {
unsigned char next, prev;
unsigned char in_use;
- int age;
+ unsigned int age;
} drm_mga_tex_region_t;
typedef struct _drm_mga_sarea {
@@ -219,9 +220,9 @@ typedef struct _drm_mga_sarea {
/* Counters for aging textures and for client-side throttling.
*/
- int last_enqueue; /* last time a buffer was enqueued */
- int last_dispatch; /* age of the most recently dispatched buffer */
- int last_quiescent; /* */
+ unsigned int last_enqueue; /* last time a buffer was enqueued */
+ unsigned int last_dispatch; /* age of the most recently dispatched buffer */
+ unsigned int last_quiescent; /* */
/* LRU lists for texture memory in agp space and on the card
@@ -237,9 +238,9 @@ typedef struct _drm_mga_sarea {
/* Device specific ioctls:
*/
typedef struct _drm_mga_clear {
- int clear_color;
- int clear_depth;
- int flags;
+ unsigned int clear_color;
+ unsigned int clear_depth;
+ unsigned int flags;
} drm_mga_clear_t;
typedef struct _drm_mga_swap {
@@ -258,4 +259,11 @@ typedef struct _drm_mga_vertex {
int discard; /* client finished with buffer? */
} drm_mga_vertex_t;
+typedef struct _drm_mga_indices {
+ int idx; /* buffer to queue */
+ unsigned int start;
+ unsigned int end;
+ int discard; /* client finished with buffer? */
+} drm_mga_indices_t;
+
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c
index b066fe9d9..4b2c835fa 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c
@@ -111,6 +111,7 @@ static drm_ioctl_desc_t mga_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_iload, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_flush_ioctl, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_indices, 1, 0 },
};
#define MGA_IOCTL_COUNT DRM_ARRAY_SIZE(mga_ioctls)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h
index fe6e4ef53..f217acb97 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h
@@ -32,18 +32,21 @@
#ifndef _MGA_DRV_H_
#define _MGA_DRV_H_
+#define MGA_BUF_IN_USE 0
+#define MGA_BUF_SWAP_PENDING 1
+#define MGA_BUF_FORCE_FIRE 2
+#define MGA_BUF_NEEDS_OVERFLOW 3
+
typedef struct {
+ u32 buffer_status;
unsigned int num_dwords;
unsigned int max_dwords;
u32 *current_dma_ptr;
u32 *head;
u32 phys_head;
+ unsigned int prim_age;
int sec_used;
int idx;
- int swap_pending;
- u32 in_use;
- atomic_t force_fire;
- atomic_t needs_overflow;
} drm_mga_prim_buf_t;
typedef struct _drm_mga_freelist {
@@ -53,31 +56,33 @@ typedef struct _drm_mga_freelist {
struct _drm_mga_freelist *prev;
} drm_mga_freelist_t;
+#define MGA_IN_DISPATCH 0
+#define MGA_IN_FLUSH 1
+#define MGA_IN_WAIT 2
+#define MGA_IN_GETBUF 3
+
typedef struct _drm_mga_private {
+ u32 dispatch_status;
+ unsigned int next_prim_age;
+ __volatile__ unsigned int last_prim_age;
int reserved_map_idx;
int buffer_map_idx;
drm_mga_sarea_t *sarea_priv;
int primary_size;
int warp_ucode_size;
int chipset;
- int frontOffset;
- int backOffset;
- int depthOffset;
- int textureOffset;
- int textureSize;
+ unsigned int frontOffset;
+ unsigned int backOffset;
+ unsigned int depthOffset;
+ unsigned int textureOffset;
+ unsigned int textureSize;
int cpp;
- int stride;
+ unsigned int stride;
int sgram;
int use_agp;
drm_mga_warp_index_t WarpIndex[MGA_MAX_G400_PIPES];
unsigned int WarpPipe;
- __volatile__ unsigned long softrap_age;
- u32 dispatch_lock;
- atomic_t in_flush;
- atomic_t in_wait;
atomic_t pending_bufs;
- unsigned int last_sync_tag;
- unsigned int sync_tag;
void *status_page;
unsigned long real_status_page;
u8 *ioremap;
@@ -86,12 +91,11 @@ typedef struct _drm_mga_private {
drm_mga_prim_buf_t *last_prim;
drm_mga_prim_buf_t *current_prim;
int current_prim_idx;
- struct pci_dev *device;
drm_mga_freelist_t *head;
drm_mga_freelist_t *tail;
wait_queue_head_t flush_queue; /* Processes waiting until flush */
wait_queue_head_t wait_queue; /* Processes waiting until interrupt */
-
+ wait_queue_head_t buf_queue; /* Processes waiting for a free buf */
/* Some validated register values:
*/
u32 mAccess;
@@ -126,7 +130,7 @@ extern int mga_dma_init(struct inode *inode, struct file *filp,
extern int mga_dma_cleanup(drm_device_t *dev);
extern int mga_flush_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-
+extern void mga_flush_write_combine(void);
extern unsigned int mga_create_sync_tag(drm_device_t *dev);
extern drm_buf_t *mga_freelist_get(drm_device_t *dev);
extern int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf);
@@ -156,6 +160,8 @@ extern int mga_iload(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int mga_vertex(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
+extern int mga_indices(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
/* mga_context.c */
extern int mga_resctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
@@ -186,6 +192,7 @@ typedef enum {
typedef struct {
drm_mga_freelist_t *my_freelist;
int discard;
+ int dispatched;
} drm_mga_buf_priv_t;
#define DWGREG0 0x1c00
@@ -206,15 +213,16 @@ typedef struct {
#define PRIM_OVERFLOW(dev, dev_priv, length) do { \
drm_mga_prim_buf_t *tmp_buf = \
- dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
- if( tmp_buf->max_dwords - tmp_buf->num_dwords < length || \
- tmp_buf->sec_used > MGA_DMA_BUF_NR/2) { \
- atomic_set(&tmp_buf->force_fire, 1); \
- mga_advance_primary(dev); \
- mga_dma_schedule(dev, 1); \
- } else if( atomic_read(&tmp_buf->needs_overflow)) { \
- mga_advance_primary(dev); \
- mga_dma_schedule(dev, 1); \
+ dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
+ if( test_bit(MGA_BUF_NEEDS_OVERFLOW, \
+ &tmp_buf->buffer_status)) { \
+ mga_advance_primary(dev); \
+ mga_dma_schedule(dev, 1); \
+ } else if( tmp_buf->max_dwords - tmp_buf->num_dwords < length ||\
+ tmp_buf->sec_used > MGA_DMA_BUF_NR/2) { \
+ set_bit(MGA_BUF_FORCE_FIRE, &tmp_buf->buffer_status); \
+ mga_advance_primary(dev); \
+ mga_dma_schedule(dev, 1); \
} \
} while(0)
@@ -266,6 +274,13 @@ drm_mga_prim_buf_t *tmp_buf = \
tmp_buf->sec_used++; \
} while (0)
+#define AGEBUF(dev_priv, buf_priv) do { \
+ drm_mga_prim_buf_t *tmp_buf = \
+ dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
+ buf_priv->my_freelist->age = tmp_buf->prim_age; \
+} while (0)
+
+
#define PRIMOUTREG(reg, val) do { \
tempIndex[outcount]=ADRINDEX(reg); \
dma_ptr[1+outcount] = val; \
@@ -356,28 +371,61 @@ drm_mga_prim_buf_t *tmp_buf = \
#define MGAREG_YTOP 0x1c98
#define MGAREG_ZORG 0x1c0c
-#define DC_atype_rstr 0x10
-#define DC_atype_blk 0x40
#define PDEA_pagpxfer_enable 0x2
+
#define WIA_wmode_suspend 0x0
#define WIA_wmode_start 0x3
#define WIA_wagp_agp 0x4
-#define DC_opcod_trap 0x4
-#define DC_arzero_enable 0x1000
-#define DC_sgnzero_enable 0x2000
-#define DC_shftzero_enable 0x4000
-#define DC_bop_SHIFT 16
-#define DC_clipdis_enable 0x80000000
-#define DC_solid_enable 0x800
-#define DC_transc_enable 0x40000000
+
+#define DC_opcod_line_open 0x0
+#define DC_opcod_autoline_open 0x1
+#define DC_opcod_line_close 0x2
+#define DC_opcod_autoline_close 0x3
+#define DC_opcod_trap 0x4
+#define DC_opcod_texture_trap 0x6
#define DC_opcod_bitblt 0x8
-#define DC_atype_rpl 0x0
-#define DC_linear_xy 0x0
-#define DC_solid_disable 0x0
-#define DC_arzero_disable 0x0
-#define DC_bltmod_bfcol 0x4000000
-#define DC_pattern_disable 0x0
-#define DC_transc_disable 0x0
+#define DC_opcod_iload 0x9
+#define DC_atype_rpl 0x0
+#define DC_atype_rstr 0x10
+#define DC_atype_zi 0x30
+#define DC_atype_blk 0x40
+#define DC_atype_i 0x70
+#define DC_linear_xy 0x0
+#define DC_linear_linear 0x80
+#define DC_zmode_nozcmp 0x0
+#define DC_zmode_ze 0x200
+#define DC_zmode_zne 0x300
+#define DC_zmode_zlt 0x400
+#define DC_zmode_zlte 0x500
+#define DC_zmode_zgt 0x600
+#define DC_zmode_zgte 0x700
+#define DC_solid_disable 0x0
+#define DC_solid_enable 0x800
+#define DC_arzero_disable 0x0
+#define DC_arzero_enable 0x1000
+#define DC_sgnzero_disable 0x0
+#define DC_sgnzero_enable 0x2000
+#define DC_shftzero_disable 0x0
+#define DC_shftzero_enable 0x4000
+#define DC_bop_SHIFT 16
+#define DC_trans_SHIFT 20
+#define DC_bltmod_bmonolef 0x0
+#define DC_bltmod_bmonowf 0x8000000
+#define DC_bltmod_bplan 0x2000000
+#define DC_bltmod_bfcol 0x4000000
+#define DC_bltmod_bu32bgr 0x6000000
+#define DC_bltmod_bu32rgb 0xe000000
+#define DC_bltmod_bu24bgr 0x16000000
+#define DC_bltmod_bu24rgb 0x1e000000
+#define DC_pattern_disable 0x0
+#define DC_pattern_enable 0x20000000
+#define DC_transc_disable 0x0
+#define DC_transc_enable 0x40000000
+#define DC_clipdis_disable 0x0
+#define DC_clipdis_enable 0x80000000
+
+#define SETADD_mode_vertlist 0x0
+
#define MGA_CLEAR_CMD (DC_opcod_trap | DC_arzero_enable | \
DC_sgnzero_enable | DC_shftzero_enable | \
@@ -392,4 +440,8 @@ drm_mga_prim_buf_t *tmp_buf = \
DC_pattern_disable | DC_transc_disable | \
DC_clipdis_enable) \
+#define MGA_FLUSH_CMD (DC_opcod_texture_trap | (0xF << DC_trans_SHIFT) |\
+ DC_arzero_enable | DC_sgnzero_enable | \
+ DC_atype_i)
+
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c
index 0a50aa4f5..3134b7853 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c
@@ -40,15 +40,23 @@ static void mgaEmitClipRect( drm_mga_private_t *dev_priv,
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int *regs = sarea_priv->ContextState;
PRIMLOCALS;
+ DRM_DEBUG("%s\n", __FUNCTION__);
/* This takes 10 dwords */
PRIMGETPTR( dev_priv );
/* Force reset of dwgctl (eliminates clip disable) */
+#if 1
PRIMOUTREG( MGAREG_DMAPAD, 0 );
- PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag - 1 );
- PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag - 1 );
+ PRIMOUTREG( MGAREG_DWGSYNC, 0 );
+ PRIMOUTREG( MGAREG_DWGSYNC, 0 );
PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
+#else
+ PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
+ PRIMOUTREG( MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000 );
+ PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
+ PRIMOUTREG( MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000 );
+#endif
PRIMOUTREG( MGAREG_DMAPAD, 0 );
PRIMOUTREG( MGAREG_CXBNDRY, ((box->x2)<<16)|(box->x1) );
@@ -63,6 +71,7 @@ static void mgaEmitContext(drm_mga_private_t *dev_priv )
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int *regs = sarea_priv->ContextState;
PRIMLOCALS;
+ DRM_DEBUG("%s\n", __FUNCTION__);
/* This takes a max of 15 dwords */
PRIMGETPTR( dev_priv );
@@ -80,13 +89,13 @@ static void mgaEmitContext(drm_mga_private_t *dev_priv )
if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
PRIMOUTREG( MGAREG_WFLAG1, regs[MGA_CTXREG_WFLAG] );
PRIMOUTREG( MGAREG_TDUALSTAGE0, regs[MGA_CTXREG_TDUAL0] );
- PRIMOUTREG( MGAREG_TDUALSTAGE1, regs[MGA_CTXREG_TDUAL1] );
+ PRIMOUTREG( MGAREG_TDUALSTAGE1, regs[MGA_CTXREG_TDUAL1] );
PRIMOUTREG( MGAREG_FCOL, regs[MGA_CTXREG_FCOL] );
} else {
PRIMOUTREG( MGAREG_FCOL, regs[MGA_CTXREG_FCOL] );
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
}
PRIMADVANCE( dev_priv );
@@ -97,27 +106,28 @@ static void mgaG200EmitTex( drm_mga_private_t *dev_priv )
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int *regs = sarea_priv->TexState[0];
PRIMLOCALS;
+ DRM_DEBUG("%s\n", __FUNCTION__);
PRIMGETPTR( dev_priv );
/* This takes 20 dwords */
- PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
- PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
- PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
- PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
+ PRIMOUTREG( MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
+ PRIMOUTREG( MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
+ PRIMOUTREG( MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
+ PRIMOUTREG( MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
- PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
- PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
- PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
- PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
+ PRIMOUTREG( MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
+ PRIMOUTREG( MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
+ PRIMOUTREG( MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
+ PRIMOUTREG( MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
- PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
- PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
- PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
- PRIMOUTREG(0x2d00 + 24*4, regs[MGA_TEXREG_WIDTH] );
+ PRIMOUTREG( MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
+ PRIMOUTREG( MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
+ PRIMOUTREG( MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
+ PRIMOUTREG( 0x2d00 + 24*4, regs[MGA_TEXREG_WIDTH] );
- PRIMOUTREG(0x2d00 + 34*4, regs[MGA_TEXREG_HEIGHT] );
+ PRIMOUTREG( 0x2d00 + 34*4, regs[MGA_TEXREG_HEIGHT] );
PRIMOUTREG( MGAREG_TEXTRANS, 0xffff );
PRIMOUTREG( MGAREG_TEXTRANSHIGH, 0xffff );
PRIMOUTREG( MGAREG_DMAPAD, 0 );
@@ -131,34 +141,35 @@ static void mgaG400EmitTex0( drm_mga_private_t *dev_priv )
unsigned int *regs = sarea_priv->TexState[0];
int multitex = sarea_priv->WarpPipe & MGA_T2;
PRIMLOCALS;
+ DRM_DEBUG("%s\n", __FUNCTION__);
PRIMGETPTR( dev_priv );
/* This takes a max of 30 dwords */
- PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
- PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
- PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
- PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
+ PRIMOUTREG( MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
+ PRIMOUTREG( MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
+ PRIMOUTREG( MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
+ PRIMOUTREG( MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
- PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
- PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
- PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
- PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
+ PRIMOUTREG( MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
+ PRIMOUTREG( MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
+ PRIMOUTREG( MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
+ PRIMOUTREG( MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
- PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
- PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
- PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
- PRIMOUTREG(0x2d00 + 49*4, 0);
+ PRIMOUTREG( MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
+ PRIMOUTREG( MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
+ PRIMOUTREG( MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
+ PRIMOUTREG( 0x2d00 + 49*4, 0 );
- PRIMOUTREG(0x2d00 + 57*4, 0);
- PRIMOUTREG(0x2d00 + 53*4, 0);
- PRIMOUTREG(0x2d00 + 61*4, 0);
+ PRIMOUTREG( 0x2d00 + 57*4, 0 );
+ PRIMOUTREG( 0x2d00 + 53*4, 0 );
+ PRIMOUTREG( 0x2d00 + 61*4, 0 );
PRIMOUTREG( MGAREG_DMAPAD, 0 );
if (!multitex) {
- PRIMOUTREG(0x2d00 + 52*4, 0x40 );
- PRIMOUTREG(0x2d00 + 60*4, 0x40 );
+ PRIMOUTREG( 0x2d00 + 52*4, 0x40 );
+ PRIMOUTREG( 0x2d00 + 60*4, 0x40 );
PRIMOUTREG( MGAREG_DMAPAD, 0 );
PRIMOUTREG( MGAREG_DMAPAD, 0 );
}
@@ -178,85 +189,127 @@ static void mgaG400EmitTex1( drm_mga_private_t *dev_priv )
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int *regs = sarea_priv->TexState[1];
PRIMLOCALS;
+ DRM_DEBUG("%s\n", __FUNCTION__);
- PRIMGETPTR(dev_priv);
+ PRIMGETPTR( dev_priv );
/* This takes 25 dwords */
- PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | TMC_map1_enable);
- PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
- PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
- PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
-
- PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
- PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
- PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
- PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
-
- PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
- PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
- PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
- PRIMOUTREG(0x2d00 + 49*4, 0);
-
- PRIMOUTREG(0x2d00 + 57*4, 0);
- PRIMOUTREG(0x2d00 + 53*4, 0);
- PRIMOUTREG(0x2d00 + 61*4, 0);
- PRIMOUTREG(0x2d00 + 52*4, regs[MGA_TEXREG_WIDTH] | 0x40 );
-
- PRIMOUTREG(0x2d00 + 60*4, regs[MGA_TEXREG_HEIGHT] | 0x40 );
+
+ PRIMOUTREG( MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | TMC_map1_enable );
+ PRIMOUTREG( MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
+ PRIMOUTREG( MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
+ PRIMOUTREG( MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
+
+ PRIMOUTREG( MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
+ PRIMOUTREG( MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
+ PRIMOUTREG( MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
+ PRIMOUTREG( MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
+
+ PRIMOUTREG( MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
+ PRIMOUTREG( MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
+ PRIMOUTREG( MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
+ PRIMOUTREG( 0x2d00 + 49*4, 0 );
+
+ PRIMOUTREG( 0x2d00 + 57*4, 0 );
+ PRIMOUTREG( 0x2d00 + 53*4, 0 );
+ PRIMOUTREG( 0x2d00 + 61*4, 0 );
+ PRIMOUTREG( 0x2d00 + 52*4, regs[MGA_TEXREG_WIDTH] | 0x40 );
+
+ PRIMOUTREG( 0x2d00 + 60*4, regs[MGA_TEXREG_HEIGHT] | 0x40 );
PRIMOUTREG( MGAREG_TEXTRANS, 0xffff );
PRIMOUTREG( MGAREG_TEXTRANSHIGH, 0xffff );
- PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
+ PRIMOUTREG( MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
+
+ PRIMADVANCE( dev_priv );
+}
+
+/* Required when switching from multitexturing to single texturing.
+ */
+static void mgaG400EmitTexFlush( drm_mga_private_t *dev_priv )
+{
+ PRIMLOCALS;
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
+ PRIMGETPTR( dev_priv );
+
+ /* This takes 15 dwords */
+
+ PRIMOUTREG( MGAREG_YDST, 0 );
+ PRIMOUTREG( MGAREG_FXLEFT, 0 );
+ PRIMOUTREG( MGAREG_FXRIGHT, 1 );
+ PRIMOUTREG( MGAREG_DWGCTL, MGA_FLUSH_CMD );
+
+ PRIMOUTREG( MGAREG_LEN + MGAREG_MGA_EXEC, 1 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DWGSYNC, 0x7000 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+
+ PRIMOUTREG( MGAREG_TEXCTL2, 0 );
+ PRIMOUTREG( MGAREG_LEN + MGAREG_MGA_EXEC, 0 );
+ PRIMOUTREG( MGAREG_TEXCTL2, 0x80 );
+ PRIMOUTREG( MGAREG_LEN + MGAREG_MGA_EXEC, 0 );
PRIMADVANCE( dev_priv );
}
-static void mgaG400EmitPipe(drm_mga_private_t *dev_priv )
+static void mgaG400EmitPipe( drm_mga_private_t *dev_priv )
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int pipe = sarea_priv->WarpPipe;
float fParam = 12800.0f;
PRIMLOCALS;
+ DRM_DEBUG("%s\n", __FUNCTION__);
- PRIMGETPTR(dev_priv);
+ PRIMGETPTR( dev_priv );
+
+ /* This takes 30 dwords */
- /* This takes 25 dwords */
-
/* Establish vertex size.
*/
if (pipe & MGA_T2) {
- PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend);
- PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001e09);
- PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x1e000000);
- PRIMOUTREG(MGAREG_WFLAG, 0);
+ PRIMOUTREG( MGAREG_WIADDR2, WIA_wmode_suspend );
+ PRIMOUTREG( MGAREG_WVRTXSZ, 0x00001e09 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+
+ PRIMOUTREG( MGAREG_WACCEPTSEQ, 0 );
+ PRIMOUTREG( MGAREG_WACCEPTSEQ, 0 );
+ PRIMOUTREG( MGAREG_WACCEPTSEQ, 0 );
+ PRIMOUTREG( MGAREG_WACCEPTSEQ, 0x1e000000 );
} else {
- PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend);
- PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001807);
- PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x18000000);
- PRIMOUTREG(MGAREG_WFLAG, 0);
+ PRIMOUTREG( MGAREG_WIADDR2, WIA_wmode_suspend );
+ PRIMOUTREG( MGAREG_WVRTXSZ, 0x00001807 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+
+ PRIMOUTREG( MGAREG_WACCEPTSEQ, 0 );
+ PRIMOUTREG( MGAREG_WACCEPTSEQ, 0 );
+ PRIMOUTREG( MGAREG_WACCEPTSEQ, 0 );
+ PRIMOUTREG( MGAREG_WACCEPTSEQ, 0x18000000 );
}
- PRIMOUTREG(MGAREG_WFLAG1, 0);
- PRIMOUTREG(0x2d00 + 56*4, *((u32 *)(&fParam)));
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_WFLAG, 0 );
+ PRIMOUTREG( MGAREG_WFLAG1, 0 );
+ PRIMOUTREG( 0x2d00 + 56*4, *((u32 *)(&fParam)) );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
- PRIMOUTREG(0x2d00 + 49*4, 0); /* Tex stage 0 */
- PRIMOUTREG(0x2d00 + 57*4, 0); /* Tex stage 0 */
- PRIMOUTREG(0x2d00 + 53*4, 0); /* Tex stage 1 */
- PRIMOUTREG(0x2d00 + 61*4, 0); /* Tex stage 1 */
+ PRIMOUTREG( 0x2d00 + 49*4, 0 ); /* Tex stage 0 */
+ PRIMOUTREG( 0x2d00 + 57*4, 0 ); /* Tex stage 0 */
+ PRIMOUTREG( 0x2d00 + 53*4, 0 ); /* Tex stage 1 */
+ PRIMOUTREG( 0x2d00 + 61*4, 0 ); /* Tex stage 1 */
- PRIMOUTREG(0x2d00 + 54*4, 0x40); /* Tex stage 0 : w */
- PRIMOUTREG(0x2d00 + 62*4, 0x40); /* Tex stage 0 : h */
- PRIMOUTREG(0x2d00 + 52*4, 0x40); /* Tex stage 1 : w */
- PRIMOUTREG(0x2d00 + 60*4, 0x40); /* Tex stage 1 : h */
+ PRIMOUTREG( 0x2d00 + 54*4, 0x40 ); /* Tex stage 0 : w */
+ PRIMOUTREG( 0x2d00 + 62*4, 0x40 ); /* Tex stage 0 : h */
+ PRIMOUTREG( 0x2d00 + 52*4, 0x40 ); /* Tex stage 1 : w */
+ PRIMOUTREG( 0x2d00 + 60*4, 0x40 ); /* Tex stage 1 : h */
/* Dma pading required due to hw bug */
- PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
- PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
- PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
- PRIMOUTREG(MGAREG_WIADDR2, (__u32)(dev_priv->WarpIndex[pipe].phys_addr |
- WIA_wmode_start | WIA_wagp_agp));
- PRIMADVANCE(dev_priv);
+ PRIMOUTREG( MGAREG_DMAPAD, 0xffffffff );
+ PRIMOUTREG( MGAREG_DMAPAD, 0xffffffff );
+ PRIMOUTREG( MGAREG_DMAPAD, 0xffffffff );
+ PRIMOUTREG( MGAREG_WIADDR2, (u32)(dev_priv->WarpIndex[pipe].phys_addr |
+ WIA_wmode_start | WIA_wagp_agp) );
+ PRIMADVANCE( dev_priv );
}
static void mgaG200EmitPipe( drm_mga_private_t *dev_priv )
@@ -264,40 +317,45 @@ static void mgaG200EmitPipe( drm_mga_private_t *dev_priv )
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int pipe = sarea_priv->WarpPipe;
PRIMLOCALS;
+ DRM_DEBUG("%s\n", __FUNCTION__);
- PRIMGETPTR(dev_priv);
+ PRIMGETPTR( dev_priv );
/* This takes 15 dwords */
- PRIMOUTREG(MGAREG_WIADDR, WIA_wmode_suspend);
- PRIMOUTREG(MGAREG_WVRTXSZ, 7);
- PRIMOUTREG(MGAREG_WFLAG, 0);
- PRIMOUTREG(0x2d00 + 24*4, 0); /* tex w/h */
+ PRIMOUTREG( MGAREG_WIADDR, WIA_wmode_suspend );
+ PRIMOUTREG( MGAREG_WVRTXSZ, 7 );
+ PRIMOUTREG( MGAREG_WFLAG, 0 );
+ PRIMOUTREG( 0x2d00 + 24*4, 0 ); /* tex w/h */
- PRIMOUTREG(0x2d00 + 25*4, 0x100);
- PRIMOUTREG(0x2d00 + 34*4, 0); /* tex w/h */
- PRIMOUTREG(0x2d00 + 42*4, 0xFFFF);
- PRIMOUTREG(0x2d00 + 60*4, 0xFFFF);
+ PRIMOUTREG( 0x2d00 + 25*4, 0x100 );
+ PRIMOUTREG( 0x2d00 + 34*4, 0 ); /* tex w/h */
+ PRIMOUTREG( 0x2d00 + 42*4, 0xFFFF );
+ PRIMOUTREG( 0x2d00 + 60*4, 0xFFFF );
/* Dma pading required due to hw bug */
- PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
- PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
- PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
- PRIMOUTREG(MGAREG_WIADDR, (__u32)(dev_priv->WarpIndex[pipe].phys_addr |
- WIA_wmode_start | WIA_wagp_agp));
+ PRIMOUTREG( MGAREG_DMAPAD, 0xffffffff );
+ PRIMOUTREG( MGAREG_DMAPAD, 0xffffffff );
+ PRIMOUTREG( MGAREG_DMAPAD, 0xffffffff );
+ PRIMOUTREG( MGAREG_WIADDR, (u32)(dev_priv->WarpIndex[pipe].phys_addr |
+ WIA_wmode_start | WIA_wagp_agp) );
- PRIMADVANCE(dev_priv);
+ PRIMADVANCE( dev_priv );
}
static void mgaEmitState( drm_mga_private_t *dev_priv )
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int dirty = sarea_priv->dirty;
+ DRM_DEBUG("%s\n", __FUNCTION__);
if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
int multitex = sarea_priv->WarpPipe & MGA_T2;
- if (sarea_priv->WarpPipe != dev_priv->WarpPipe) {
+ if (sarea_priv->WarpPipe != dev_priv->WarpPipe) {
+ if ((dev_priv->WarpPipe & MGA_T2) && !multitex) {
+ mgaG400EmitTexFlush( dev_priv );
+ }
mgaG400EmitPipe( dev_priv );
dev_priv->WarpPipe = sarea_priv->WarpPipe;
}
@@ -342,6 +400,8 @@ static int mgaVerifyContext(drm_mga_private_t *dev_priv )
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int *regs = sarea_priv->ContextState;
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
if (regs[MGA_CTXREG_DSTORG] != dev_priv->frontOffset &&
regs[MGA_CTXREG_DSTORG] != dev_priv->backOffset) {
DRM_DEBUG("BAD DSTORG: %x (front %x, back %x)\n\n",
@@ -361,6 +421,8 @@ static int mgaVerifyTex(drm_mga_private_t *dev_priv,
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
if ((sarea_priv->TexState[unit][MGA_TEXREG_ORG] & 0x3) == 0x1) {
DRM_DEBUG("BAD TEXREG_ORG: %x, unit %d\n",
sarea_priv->TexState[unit][MGA_TEXREG_ORG],
@@ -378,6 +440,8 @@ static int mgaVerifyState( drm_mga_private_t *dev_priv )
unsigned int dirty = sarea_priv->dirty;
int rv = 0;
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
@@ -408,6 +472,8 @@ static int mgaVerifyIload( drm_mga_private_t *dev_priv,
unsigned long bus_address,
unsigned int dstOrg, int length )
{
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
if(dstOrg < dev_priv->textureOffset ||
dstOrg + length >
(dev_priv->textureOffset + dev_priv->textureSize)) {
@@ -431,35 +497,34 @@ static void mga_dma_dispatch_tex_blit( drm_device_t *dev,
int use_agp = PDEA_pagpxfer_enable | 0x00000001;
u16 y2;
PRIMLOCALS;
+ DRM_DEBUG("%s\n", __FUNCTION__);
y2 = length / 64;
- PRIM_OVERFLOW(dev, dev_priv, 30);
+ PRIM_OVERFLOW( dev, dev_priv, 30 );
PRIMGETPTR( dev_priv );
- dev_priv->last_sync_tag = mga_create_sync_tag(dev);
-
- PRIMOUTREG( MGAREG_DSTORG, destOrg);
- PRIMOUTREG( MGAREG_MACCESS, 0x00000000);
+ PRIMOUTREG( MGAREG_DSTORG, destOrg );
+ PRIMOUTREG( MGAREG_MACCESS, 0x00000000 );
DRM_DEBUG("srcorg : %lx\n", bus_address | use_agp);
- PRIMOUTREG( MGAREG_SRCORG, (u32) bus_address | use_agp);
- PRIMOUTREG( MGAREG_AR5, 64);
-
- PRIMOUTREG( MGAREG_PITCH, 64);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DWGCTL, MGA_COPY_CMD);
-
- PRIMOUTREG(MGAREG_AR0, 63);
- PRIMOUTREG(MGAREG_AR3, 0);
- PRIMOUTREG(MGAREG_FXBNDRY, (63 << 16));
- PRIMOUTREG(MGAREG_YDSTLEN+MGAREG_MGA_EXEC, y2);
+ PRIMOUTREG( MGAREG_SRCORG, (u32) bus_address | use_agp );
+ PRIMOUTREG( MGAREG_AR5, 64 );
+
+ PRIMOUTREG( MGAREG_PITCH, 64 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DWGCTL, MGA_COPY_CMD );
+
+ PRIMOUTREG( MGAREG_AR0, 63 );
+ PRIMOUTREG( MGAREG_AR3, 0 );
+ PRIMOUTREG( MGAREG_FXBNDRY, (63 << 16) );
+ PRIMOUTREG( MGAREG_YDSTLEN+MGAREG_MGA_EXEC, y2 );
- PRIMOUTREG( MGAREG_SRCORG, 0);
- PRIMOUTREG( MGAREG_PITCH, dev_priv->stride / dev_priv->cpp);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
- PRIMADVANCE(dev_priv);
+ PRIMOUTREG( MGAREG_SRCORG, 0 );
+ PRIMOUTREG( MGAREG_PITCH, dev_priv->stride / dev_priv->cpp );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMADVANCE( dev_priv );
}
static void mga_dma_dispatch_vertex(drm_device_t *dev,
@@ -474,33 +539,100 @@ static void mga_dma_dispatch_vertex(drm_device_t *dev,
int i = 0;
int primary_needed;
PRIMLOCALS;
+ DRM_DEBUG("%s\n", __FUNCTION__);
DRM_DEBUG("dispatch vertex %d addr 0x%lx, "
"length 0x%x nbox %d dirty %x\n",
buf->idx, address, length,
sarea_priv->nbox, sarea_priv->dirty);
+ DRM_DEBUG("used : %d, total : %d\n", buf->used, buf->total);
+ if(sarea_priv->WarpPipe & MGA_T2) {
+ if ((buf->used/4) % 10)
+ DRM_DEBUG("Multitex Buf is not aligned properly!!!\n");
+ } else {
+ if ((buf->used/4) % 8)
+ DRM_DEBUG("Buf is not aligned properly!!!\n");
+ }
- dev_priv->last_sync_tag = mga_create_sync_tag(dev);
+ if (buf->used) {
+ /* WARNING: if you change any of the state functions verify
+ * these numbers (Overestimating this doesn't hurt).
+ */
+ buf_priv->dispatched = 1;
+ primary_needed = (30+15+15+30+25+
+ 10 +
+ 15 * MGA_NR_SAREA_CLIPRECTS);
+ PRIM_OVERFLOW(dev, dev_priv, primary_needed);
+ mgaEmitState( dev_priv );
+
+ do {
+ if (i < sarea_priv->nbox) {
+ DRM_DEBUG("idx %d Emit box %d/%d:"
+ "%d,%d - %d,%d\n",
+ buf->idx,
+ i, sarea_priv->nbox,
+ sarea_priv->boxes[i].x1,
+ sarea_priv->boxes[i].y1,
+ sarea_priv->boxes[i].x2,
+ sarea_priv->boxes[i].y2);
+
+ mgaEmitClipRect( dev_priv,
+ &sarea_priv->boxes[i] );
+ }
+
+ PRIMGETPTR( dev_priv );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_SECADDRESS,
+ ((u32)address) | TT_VERTEX );
+ PRIMOUTREG( MGAREG_SECEND,
+ (((u32)(address + length)) | use_agp) );
+ PRIMADVANCE( dev_priv );
+ } while (++i < sarea_priv->nbox);
+ }
- if (buf_priv->discard) {
- buf_priv->my_freelist->age = dev_priv->last_sync_tag;
+ if (buf_priv->discard) {
+ if (buf_priv->dispatched == 1) AGEBUF(dev_priv, buf_priv);
+ buf_priv->dispatched = 0;
mga_freelist_put(dev, buf);
}
- /* WARNING: if you change any of the state functions verify
- * these numbers (Overestimating this doesn't hurt).
- */
- primary_needed = (25+15+30+25+
- 10 +
- 15 * MGA_NR_SAREA_CLIPRECTS);
+}
- PRIM_OVERFLOW(dev, dev_priv, primary_needed);
- mgaEmitState( dev_priv );
+static void mga_dma_dispatch_indices(drm_device_t *dev,
+ drm_buf_t *buf,
+ unsigned int start,
+ unsigned int end)
+{
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ drm_mga_buf_priv_t *buf_priv = buf->dev_private;
+ drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ unsigned int address = (unsigned int)buf->bus_address;
+ int use_agp = PDEA_pagpxfer_enable;
+ int i = 0;
+ int primary_needed;
+ PRIMLOCALS;
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
+ DRM_DEBUG("dispatch indices %d addr 0x%x, "
+ "start 0x%x end 0x%x nbox %d dirty %x\n",
+ buf->idx, address, start, end,
+ sarea_priv->nbox, sarea_priv->dirty);
+
+ if (start != end) {
+ /* WARNING: if you change any of the state functions verify
+ * these numbers (Overestimating this doesn't hurt).
+ */
+ buf_priv->dispatched = 1;
+ primary_needed = (25+15+30+25+
+ 10 +
+ 15 * MGA_NR_SAREA_CLIPRECTS);
+ PRIM_OVERFLOW( dev, dev_priv, primary_needed );
+ mgaEmitState( dev_priv );
- if (buf->used) {
do {
if (i < sarea_priv->nbox) {
DRM_DEBUG("idx %d Emit box %d/%d:"
@@ -515,25 +647,23 @@ static void mga_dma_dispatch_vertex(drm_device_t *dev,
mgaEmitClipRect( dev_priv,
&sarea_priv->boxes[i] );
}
-
- PRIMGETPTR(dev_priv);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_SECADDRESS,
- ((__u32)address) | TT_VERTEX);
- PRIMOUTREG( MGAREG_SECEND,
- (((__u32)(address + length)) |
- use_agp));
+
+ PRIMGETPTR( dev_priv );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_SETUPADDRESS,
+ ((address + start) |
+ SETADD_mode_vertlist) );
+ PRIMOUTREG( MGAREG_SETUPEND,
+ ((address + end) | use_agp) );
PRIMADVANCE( dev_priv );
} while (++i < sarea_priv->nbox);
}
-
- PRIMGETPTR( dev_priv );
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DWGSYNC, dev_priv->last_sync_tag);
- PRIMADVANCE( dev_priv );
+ if (buf_priv->discard) {
+ if (buf_priv->dispatched == 1) AGEBUF(dev_priv, buf_priv);
+ buf_priv->dispatched = 0;
+ mga_freelist_put(dev, buf);
+ }
}
@@ -550,6 +680,7 @@ static void mga_dma_dispatch_clear( drm_device_t *dev, int flags,
int i;
int primary_needed;
PRIMLOCALS;
+ DRM_DEBUG("%s\n", __FUNCTION__);
if ( dev_priv->sgram )
cmd = MGA_CLEAR_CMD | DC_atype_blk;
@@ -557,10 +688,9 @@ static void mga_dma_dispatch_clear( drm_device_t *dev, int flags,
cmd = MGA_CLEAR_CMD | DC_atype_rstr;
primary_needed = nbox * 70;
- if(primary_needed == 0) primary_needed = 70;
- PRIM_OVERFLOW(dev, dev_priv, primary_needed);
+ if (primary_needed == 0) primary_needed = 70;
+ PRIM_OVERFLOW( dev, dev_priv, primary_needed );
PRIMGETPTR( dev_priv );
- dev_priv->last_sync_tag = mga_create_sync_tag(dev);
for (i = 0 ; i < nbox ; i++) {
unsigned int height = pbox[i].y2 - pbox[i].y1;
@@ -571,55 +701,50 @@ static void mga_dma_dispatch_clear( drm_device_t *dev, int flags,
if ( flags & MGA_FRONT ) {
DRM_DEBUG("clear front\n");
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
- PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
-
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_FCOL, clear_color);
- PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
- PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
+ PRIMOUTREG( MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
+
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_FCOL, clear_color );
+ PRIMOUTREG( MGAREG_DSTORG, dev_priv->frontOffset );
+ PRIMOUTREG( MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd );
}
if ( flags & MGA_BACK ) {
DRM_DEBUG("clear back\n");
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
- PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
+ PRIMOUTREG( MGAREG_YDSTLEN, (pbox[i].y1<<16)|height );
+ PRIMOUTREG( MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1 );
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_FCOL, clear_color);
- PRIMOUTREG(MGAREG_DSTORG, dev_priv->backOffset);
- PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_FCOL, clear_color );
+ PRIMOUTREG( MGAREG_DSTORG, dev_priv->backOffset );
+ PRIMOUTREG( MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd );
}
if ( flags & MGA_DEPTH ) {
DRM_DEBUG("clear depth\n");
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
- PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
-
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_FCOL, clear_zval);
- PRIMOUTREG(MGAREG_DSTORG, dev_priv->depthOffset);
- PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_YDSTLEN, (pbox[i].y1<<16)|height );
+ PRIMOUTREG( MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1 );
+
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_FCOL, clear_zval );
+ PRIMOUTREG( MGAREG_DSTORG, dev_priv->depthOffset );
+ PRIMOUTREG( MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd );
}
}
/* Force reset of DWGCTL */
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
-
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
- PRIMADVANCE(dev_priv);
+ PRIMADVANCE( dev_priv );
}
static void mga_dma_dispatch_swap( drm_device_t *dev )
@@ -632,23 +757,22 @@ static void mga_dma_dispatch_swap( drm_device_t *dev )
int i;
int primary_needed;
PRIMLOCALS;
+ DRM_DEBUG("%s\n", __FUNCTION__);
primary_needed = nbox * 5;
primary_needed += 60;
PRIM_OVERFLOW(dev, dev_priv, primary_needed);
PRIMGETPTR( dev_priv );
- dev_priv->last_sync_tag = mga_create_sync_tag(dev);
+ PRIMOUTREG( MGAREG_DSTORG, dev_priv->frontOffset );
+ PRIMOUTREG( MGAREG_MACCESS, dev_priv->mAccess );
+ PRIMOUTREG( MGAREG_SRCORG, dev_priv->backOffset );
+ PRIMOUTREG( MGAREG_AR5, dev_priv->stride/2 );
- PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
- PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess);
- PRIMOUTREG(MGAREG_SRCORG, dev_priv->backOffset);
- PRIMOUTREG(MGAREG_AR5, dev_priv->stride/2);
-
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD);
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DWGCTL, MGA_COPY_CMD );
for (i = 0 ; i < nbox; i++) {
unsigned int h = pbox[i].y2 - pbox[i].y1;
@@ -658,23 +782,19 @@ static void mga_dma_dispatch_swap( drm_device_t *dev )
pbox[i].x1, pbox[i].y1,
pbox[i].x2, pbox[i].y2);
- PRIMOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1);
- PRIMOUTREG(MGAREG_AR3, start + pbox[i].x1);
- PRIMOUTREG(MGAREG_FXBNDRY, pbox[i].x1|((pbox[i].x2 - 1)<<16));
- PRIMOUTREG(MGAREG_YDSTLEN+MGAREG_MGA_EXEC, (pbox[i].y1<<16)|h);
+ PRIMOUTREG( MGAREG_AR0, start + pbox[i].x2 - 1 );
+ PRIMOUTREG( MGAREG_AR3, start + pbox[i].x1 );
+ PRIMOUTREG( MGAREG_FXBNDRY, pbox[i].x1|((pbox[i].x2 - 1)<<16) );
+ PRIMOUTREG( MGAREG_YDSTLEN+MGAREG_MGA_EXEC, (pbox[i].y1<<16)|h );
}
/* Force reset of DWGCTL */
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_DMAPAD, 0 );
+ PRIMOUTREG( MGAREG_SRCORG, 0 );
PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
- PRIMOUTREG( MGAREG_SRCORG, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
- PRIMADVANCE(dev_priv);
+ PRIMADVANCE( dev_priv );
}
int mga_clear_bufs(struct inode *inode, struct file *filp,
@@ -684,12 +804,11 @@ int mga_clear_bufs(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- __volatile__ unsigned int *status =
- (__volatile__ unsigned int *)dev_priv->status_page;
drm_mga_clear_t clear;
copy_from_user_ret(&clear, (drm_mga_clear_t *)arg, sizeof(clear),
-EFAULT);
+ DRM_DEBUG("%s\n", __FUNCTION__);
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
DRM_ERROR("mga_clear_bufs called without lock held\n");
@@ -706,8 +825,8 @@ int mga_clear_bufs(struct inode *inode, struct file *filp,
clear.clear_color,
clear.clear_depth );
PRIMUPDATE(dev_priv);
+ mga_flush_write_combine();
mga_dma_schedule(dev, 1);
- sarea_priv->last_dispatch = status[1];
return 0;
}
@@ -718,8 +837,7 @@ int mga_swap_bufs(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- __volatile__ unsigned int *status =
- (__volatile__ unsigned int *)dev_priv->status_page;
+ DRM_DEBUG("%s\n", __FUNCTION__);
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
DRM_ERROR("mga_swap_bufs called without lock held\n");
@@ -734,10 +852,9 @@ int mga_swap_bufs(struct inode *inode, struct file *filp,
dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;
mga_dma_dispatch_swap( dev );
PRIMUPDATE(dev_priv);
- set_bit(0, &dev_priv->current_prim->swap_pending);
- dev_priv->current_prim->swap_pending = 1;
+ set_bit(MGA_BUF_SWAP_PENDING, &dev_priv->current_prim->buffer_status);
+ mga_flush_write_combine();
mga_dma_schedule(dev, 1);
- sarea_priv->last_dispatch = status[1];
return 0;
}
@@ -749,12 +866,11 @@ int mga_iload(struct inode *inode, struct file *filp,
drm_device_dma_t *dma = dev->dma;
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- __volatile__ unsigned int *status =
- (__volatile__ unsigned int *)dev_priv->status_page;
drm_buf_t *buf;
drm_mga_buf_priv_t *buf_priv;
drm_mga_iload_t iload;
unsigned long bus_address;
+ DRM_DEBUG("%s\n", __FUNCTION__);
DRM_DEBUG("Starting Iload\n");
copy_from_user_ret(&iload, (drm_mga_iload_t *)arg, sizeof(iload),
@@ -783,11 +899,11 @@ int mga_iload(struct inode *inode, struct file *filp,
mga_dma_dispatch_tex_blit(dev, bus_address, iload.length,
iload.destOrg);
- buf_priv->my_freelist->age = dev_priv->last_sync_tag;
+ AGEBUF(dev_priv, buf_priv);
buf_priv->discard = 1;
mga_freelist_put(dev, buf);
+ mga_flush_write_combine();
mga_dma_schedule(dev, 1);
- sarea_priv->last_dispatch = status[1];
return 0;
}
@@ -797,13 +913,11 @@ int mga_vertex(struct inode *inode, struct file *filp,
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
- drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- __volatile__ unsigned int *status =
- (__volatile__ unsigned int *)dev_priv->status_page;
drm_device_dma_t *dma = dev->dma;
drm_buf_t *buf;
drm_mga_buf_priv_t *buf_priv;
drm_mga_vertex_t vertex;
+ DRM_DEBUG("%s\n", __FUNCTION__);
copy_from_user_ret(&vertex, (drm_mga_vertex_t *)arg, sizeof(vertex),
-EFAULT);
@@ -822,25 +936,75 @@ int mga_vertex(struct inode *inode, struct file *filp,
buf_priv->discard = vertex.discard;
if (!mgaVerifyState(dev_priv)) {
- if (vertex.discard) {
- buf_priv->my_freelist->age = dev_priv->last_sync_tag;
- mga_freelist_put(dev, buf);
+ if (vertex.discard) {
+ if(buf_priv->dispatched == 1) AGEBUF(dev_priv, buf_priv);
+ buf_priv->dispatched = 0;
+ mga_freelist_put(dev, buf);
}
+ DRM_DEBUG("bad state\n");
return -EINVAL;
}
mga_dma_dispatch_vertex(dev, buf);
PRIMUPDATE(dev_priv);
+ mga_flush_write_combine();
mga_dma_schedule(dev, 1);
- sarea_priv->last_dispatch = status[1];
return 0;
}
+
+int mga_indices(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_t *buf;
+ drm_mga_buf_priv_t *buf_priv;
+ drm_mga_indices_t indices;
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
+ copy_from_user_ret(&indices, (drm_mga_indices_t *)arg, sizeof(indices),
+ -EFAULT);
+
+ if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("mga_indices called without lock held\n");
+ return -EINVAL;
+ }
+
+ DRM_DEBUG("mga_indices\n");
+
+ buf = dma->buflist[ indices.idx ];
+ buf_priv = buf->dev_private;
+
+ buf_priv->discard = indices.discard;
+
+ if (!mgaVerifyState(dev_priv)) {
+ if (indices.discard) {
+ if(buf_priv->dispatched == 1) AGEBUF(dev_priv, buf_priv);
+ buf_priv->dispatched = 0;
+ mga_freelist_put(dev, buf);
+ }
+ return -EINVAL;
+ }
+
+ mga_dma_dispatch_indices(dev, buf, indices.start, indices.end);
+
+ PRIMUPDATE(dev_priv);
+ mga_flush_write_combine();
+ mga_dma_schedule(dev, 1);
+ return 0;
+}
+
+
+
static int mga_dma_get_buffers(drm_device_t *dev, drm_dma_t *d)
{
int i;
drm_buf_t *buf;
+ DRM_DEBUG("%s\n", __FUNCTION__);
for (i = d->granted_count; i < d->request_count; i++) {
buf = mga_freelist_get(dev);
@@ -865,12 +1029,9 @@ int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd,
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_device_dma_t *dma = dev->dma;
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
- drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- __volatile__ unsigned int *status =
- (__volatile__ unsigned int *)dev_priv->status_page;
int retcode = 0;
drm_dma_t d;
+ DRM_DEBUG("%s\n", __FUNCTION__);
copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT);
DRM_DEBUG("%d %d: %d send, %d req\n",
@@ -906,6 +1067,5 @@ int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd,
DRM_DEBUG("%d returning, granted = %d\n",
current->pid, d.granted_count);
copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT);
- sarea_priv->last_dispatch = status[1];
return retcode;
}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c
index bb8e18e0e..ba6dee00d 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c
@@ -400,6 +400,7 @@ static int _drm_vma_info(char *buf, char **start, off_t offset, int len,
pgprot & _PAGE_GLOBAL ? 'g' : 'l' );
#endif
DRM_PROC_PRINT("\n");
+#if 0
for (i = vma->vm_start; i < vma->vm_end; i += PAGE_SIZE) {
pgd = pgd_offset(vma->vm_mm, i);
pmd = pmd_offset(pgd, i);
@@ -420,6 +421,7 @@ static int _drm_vma_info(char *buf, char **start, off_t offset, int len,
DRM_PROC_PRINT(" 0x%08lx\n", i);
}
}
+#endif
}
return len;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_bufs.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_bufs.c
new file mode 100644
index 000000000..bad6c5714
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_bufs.c
@@ -0,0 +1,309 @@
+/* r128_bufs.c -- IOCTLs to manage buffers -*- linux-c -*-
+ * Created: Wed Apr 12 16:19:08 2000 by kevin@precisioninsight.com
+ *
+ * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Kevin E. Martin <kevin@precisioninsight.com>
+ * Rickard E. (Rik) Faith <faith@precisioninsight.com>
+ * Jeff Hartmann <jhartmann@precisioninsight.com>
+ *
+ * $XFree86$
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+#include "r128_drv.h"
+#include "linux/un.h"
+
+
+#ifdef DRM_AGP
+int r128_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_desc_t request;
+ drm_buf_entry_t *entry;
+ drm_buf_t *buf;
+ unsigned long offset;
+ unsigned long agp_offset;
+ int count;
+ int order;
+ int size;
+ int alignment;
+ int page_order;
+ int total;
+ int byte_count;
+ int i;
+
+ if (!dma) return -EINVAL;
+
+ copy_from_user_ret(&request,
+ (drm_buf_desc_t *)arg,
+ sizeof(request),
+ -EFAULT);
+
+ count = request.count;
+ order = drm_order(request.size);
+ size = 1 << order;
+
+ alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size):size;
+ page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+ total = PAGE_SIZE << page_order;
+
+ byte_count = 0;
+ agp_offset = dev->agp->base + request.agp_start;
+
+ DRM_DEBUG("count: %d\n", count);
+ DRM_DEBUG("order: %d\n", order);
+ DRM_DEBUG("size: %d\n", size);
+ DRM_DEBUG("agp_offset: %ld\n", agp_offset);
+ DRM_DEBUG("alignment: %d\n", alignment);
+ DRM_DEBUG("page_order: %d\n", page_order);
+ DRM_DEBUG("total: %d\n", total);
+
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
+ if (dev->queue_count) return -EBUSY; /* Not while in use */
+
+ spin_lock(&dev->count_lock);
+ if (dev->buf_use) {
+ spin_unlock(&dev->count_lock);
+ return -EBUSY;
+ }
+ atomic_inc(&dev->buf_alloc);
+ spin_unlock(&dev->count_lock);
+
+ down(&dev->struct_sem);
+ entry = &dma->bufs[order];
+ if (entry->buf_count) {
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
+ return -ENOMEM; /* May only call once for each order */
+ }
+
+ entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
+ DRM_MEM_BUFS);
+ if (!entry->buflist) {
+ up(&dev->struct_sem);
+ atomic_dec(&dev->buf_alloc);
+ return -ENOMEM;
+ }
+ memset(entry->buflist, 0, count * sizeof(*entry->buflist));
+
+ entry->buf_size = size;
+ entry->page_order = page_order;
+ offset = 0;
+
+ for (offset = 0;
+ entry->buf_count < count;
+ offset += alignment, ++entry->buf_count) {
+ buf = &entry->buflist[entry->buf_count];
+ buf->idx = dma->buf_count + entry->buf_count;
+ buf->total = alignment;
+ buf->order = order;
+ buf->used = 0;
+ buf->offset = (dma->byte_count + offset);
+ buf->address = (void *)(agp_offset + offset);
+ buf->next = NULL;
+ buf->waiting = 0;
+ buf->pending = 0;
+ init_waitqueue_head(&buf->dma_wait);
+ buf->pid = 0;
+
+ buf->dev_priv_size = sizeof(drm_r128_buf_priv_t);
+ buf->dev_private = drm_alloc(sizeof(drm_r128_buf_priv_t),
+ DRM_MEM_BUFS);
+ memset(buf->dev_private, 0, buf->dev_priv_size);
+
+#if DRM_DMA_HISTOGRAM
+ buf->time_queued = 0;
+ buf->time_dispatched = 0;
+ buf->time_completed = 0;
+ buf->time_freed = 0;
+#endif
+
+ byte_count += PAGE_SIZE << page_order;
+
+ DRM_DEBUG("buffer %d @ %p\n",
+ entry->buf_count, buf->address);
+ }
+
+ DRM_DEBUG("byte_count: %d\n", byte_count);
+
+ dma->buflist = drm_realloc(dma->buflist,
+ dma->buf_count * sizeof(*dma->buflist),
+ (dma->buf_count + entry->buf_count)
+ * sizeof(*dma->buflist),
+ DRM_MEM_BUFS);
+ for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++)
+ dma->buflist[i] = &entry->buflist[i - dma->buf_count];
+
+ dma->buf_count += entry->buf_count;
+ dma->byte_count += byte_count;
+
+ drm_freelist_create(&entry->freelist, entry->buf_count);
+ for (i = 0; i < entry->buf_count; i++) {
+ drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
+ }
+
+ up(&dev->struct_sem);
+
+ request.count = entry->buf_count;
+ request.size = size;
+
+ copy_to_user_ret((drm_buf_desc_t *)arg,
+ &request,
+ sizeof(request),
+ -EFAULT);
+
+ dma->flags = _DRM_DMA_USE_AGP;
+
+ atomic_dec(&dev->buf_alloc);
+ return 0;
+}
+#endif
+
+int r128_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_buf_desc_t request;
+
+ if (!dev_priv || dev_priv->is_pci) return -EINVAL;
+
+ copy_from_user_ret(&request,
+ (drm_buf_desc_t *)arg,
+ sizeof(request),
+ -EFAULT);
+
+#ifdef DRM_AGP
+ if (request.flags & _DRM_AGP_BUFFER)
+ return r128_addbufs_agp(inode, filp, cmd, arg);
+ else
+#endif
+ return -EINVAL;
+}
+
+int r128_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_device_dma_t *dma = dev->dma;
+ int retcode = 0;
+ const int zero = 0;
+ unsigned long virtual;
+ unsigned long address;
+ drm_buf_map_t request;
+ int i;
+
+ if (!dma || !dev_priv || dev_priv->is_pci) return -EINVAL;
+
+ DRM_DEBUG("\n");
+
+ spin_lock(&dev->count_lock);
+ if (atomic_read(&dev->buf_alloc)) {
+ spin_unlock(&dev->count_lock);
+ return -EBUSY;
+ }
+ ++dev->buf_use; /* Can't allocate more after this call */
+ spin_unlock(&dev->count_lock);
+
+ copy_from_user_ret(&request,
+ (drm_buf_map_t *)arg,
+ sizeof(request),
+ -EFAULT);
+
+ if (request.count >= dma->buf_count) {
+ if (dma->flags & _DRM_DMA_USE_AGP) {
+ drm_map_t *map;
+
+ map = dev_priv->agp_vertbufs;
+ if (!map) {
+ retcode = -EINVAL;
+ goto done;
+ }
+
+ down(&current->mm->mmap_sem);
+ virtual = do_mmap(filp, 0, map->size,
+ PROT_READ|PROT_WRITE,
+ MAP_SHARED,
+ (unsigned long)map->offset);
+ up(&current->mm->mmap_sem);
+ } else {
+ down(&current->mm->mmap_sem);
+ virtual = do_mmap(filp, 0, dma->byte_count,
+ PROT_READ|PROT_WRITE, MAP_SHARED, 0);
+ up(&current->mm->mmap_sem);
+ }
+ if (virtual > -1024UL) {
+ /* Real error */
+ retcode = (signed long)virtual;
+ goto done;
+ }
+ request.virtual = (void *)virtual;
+
+ for (i = 0; i < dma->buf_count; i++) {
+ if (copy_to_user(&request.list[i].idx,
+ &dma->buflist[i]->idx,
+ sizeof(request.list[0].idx))) {
+ retcode = -EFAULT;
+ goto done;
+ }
+ if (copy_to_user(&request.list[i].total,
+ &dma->buflist[i]->total,
+ sizeof(request.list[0].total))) {
+ retcode = -EFAULT;
+ goto done;
+ }
+ if (copy_to_user(&request.list[i].used,
+ &zero,
+ sizeof(zero))) {
+ retcode = -EFAULT;
+ goto done;
+ }
+ address = virtual + dma->buflist[i]->offset;
+ if (copy_to_user(&request.list[i].address,
+ &address,
+ sizeof(address))) {
+ retcode = -EFAULT;
+ goto done;
+ }
+ }
+ }
+ done:
+ request.count = dma->buf_count;
+ DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
+
+ copy_to_user_ret((drm_buf_map_t *)arg,
+ &request,
+ sizeof(request),
+ -EFAULT);
+
+ return retcode;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_context.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_context.c
new file mode 100644
index 000000000..d288fd284
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_context.c
@@ -0,0 +1,214 @@
+/* r128_context.c -- IOCTLs for r128 contexts -*- linux-c -*-
+ * Created: Mon Dec 13 09:51:35 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Rickard E. (Rik) Faith <faith@precisioninsight.com>
+ *
+ * $XFree86$
+ *
+ */
+
+#include <linux/sched.h>
+
+#define __NO_VERSION__
+#include "drmP.h"
+#include "r128_drv.h"
+
+extern drm_ctx_t r128_res_ctx;
+
+static int r128_alloc_queue(drm_device_t *dev)
+{
+#if 0
+ static int context = 0;
+#endif
+
+ return drm_ctxbitmap_next(dev);
+}
+
+int r128_context_switch(drm_device_t *dev, int old, int new)
+{
+ char buf[64];
+
+ atomic_inc(&dev->total_ctx);
+
+ if (test_and_set_bit(0, &dev->context_flag)) {
+ DRM_ERROR("Reentering -- FIXME\n");
+ return -EBUSY;
+ }
+
+#if DRM_DMA_HISTOGRAM
+ dev->ctx_start = get_cycles();
+#endif
+
+ DRM_DEBUG("Context switch from %d to %d\n", old, new);
+
+ if (new == dev->last_context) {
+ clear_bit(0, &dev->context_flag);
+ return 0;
+ }
+
+ if (drm_flags & DRM_FLAG_NOCTX) {
+ r128_context_switch_complete(dev, new);
+ } else {
+ sprintf(buf, "C %d %d\n", old, new);
+ drm_write_string(dev, buf);
+ }
+
+ return 0;
+}
+
+int r128_context_switch_complete(drm_device_t *dev, int new)
+{
+ dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
+ dev->last_switch = jiffies;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("Lock isn't held after context switch\n");
+ }
+
+ /* If a context switch is ever initiated
+ when the kernel holds the lock, release
+ that lock here. */
+#if DRM_DMA_HISTOGRAM
+ atomic_inc(&dev->histo.ctx[drm_histogram_slot(get_cycles()
+ - dev->ctx_start)]);
+
+#endif
+ clear_bit(0, &dev->context_flag);
+ wake_up(&dev->context_wait);
+
+ return 0;
+}
+
+
+int r128_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_ctx_res_t res;
+ drm_ctx_t ctx;
+ int i;
+
+ DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
+ copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT);
+ if (res.count >= DRM_RESERVED_CONTEXTS) {
+ memset(&ctx, 0, sizeof(ctx));
+ for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
+ ctx.handle = i;
+ copy_to_user_ret(&res.contexts[i],
+ &i,
+ sizeof(i),
+ -EFAULT);
+ }
+ }
+ res.count = DRM_RESERVED_CONTEXTS;
+ copy_to_user_ret((drm_ctx_res_t *)arg, &res, sizeof(res), -EFAULT);
+ return 0;
+}
+
+
+int r128_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_t ctx;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+ if ((ctx.handle = r128_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
+ /* Skip kernel's context and get a new one. */
+ ctx.handle = r128_alloc_queue(dev);
+ }
+ DRM_DEBUG("%d\n", ctx.handle);
+ if (ctx.handle == -1) {
+ DRM_DEBUG("Not enough free contexts.\n");
+ /* Should this return -EBUSY instead? */
+ return -ENOMEM;
+ }
+
+ copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
+ return 0;
+}
+
+int r128_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_ctx_t ctx;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT);
+ if (ctx.flags==_DRM_CONTEXT_PRESERVED)
+ r128_res_ctx.handle=ctx.handle;
+ return 0;
+}
+
+int r128_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_ctx_t ctx;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT);
+ /* This is 0, because we don't hanlde any context flags */
+ ctx.flags = 0;
+ copy_to_user_ret((drm_ctx_t*)arg, &ctx, sizeof(ctx), -EFAULT);
+ return 0;
+}
+
+int r128_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_t ctx;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+ DRM_DEBUG("%d\n", ctx.handle);
+ return r128_context_switch(dev, dev->last_context, ctx.handle);
+}
+
+int r128_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_t ctx;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+ DRM_DEBUG("%d\n", ctx.handle);
+ r128_context_switch_complete(dev, ctx.handle);
+
+ return 0;
+}
+
+int r128_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_t ctx;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+ DRM_DEBUG("%d\n", ctx.handle);
+ drm_ctxbitmap_free(dev, ctx.handle);
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_dma.c
new file mode 100644
index 000000000..860c41885
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_dma.c
@@ -0,0 +1,908 @@
+/* r128_drv.c -- ATI Rage 128 driver -*- linux-c -*-
+ * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com
+ *
+ * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $XFree86$
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+#include "r128_drv.h"
+
+#include <linux/interrupt.h> /* For task queue support */
+#include <linux/delay.h>
+
+
+
+#define DO_REMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size)
+
+#define DO_REMAPFREE(_m) \
+ do { \
+ if ((_m)->handle && (_m)->size) \
+ drm_ioremapfree((_m)->handle, (_m)->size); \
+ } while (0)
+
+#define DO_FIND_MAP(_m, _o) \
+ do { \
+ int _i; \
+ for (_i = 0; _i < dev->map_count; _i++) { \
+ if (dev->maplist[_i]->offset == _o) { \
+ _m = dev->maplist[_i]; \
+ break; \
+ } \
+ } \
+ } while (0)
+
+
+#define R128_MAX_VBUF_AGE 0x10000000
+#define R128_VB_AGE_REG R128_GUI_SCRATCH_REG0
+
+int R128_READ_PLL(drm_device_t *dev, int addr)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+
+ R128_WRITE8(R128_CLOCK_CNTL_INDEX, addr & 0x1f);
+ return R128_READ(R128_CLOCK_CNTL_DATA);
+}
+
+static void r128_flush_write_combine(void)
+{
+ int xchangeDummy;
+
+ __asm__ volatile("push %%eax ;"
+ "xchg %%eax, %0 ;"
+ "pop %%eax" : : "m" (xchangeDummy));
+ __asm__ volatile("push %%eax ;"
+ "push %%ebx ;"
+ "push %%ecx ;"
+ "push %%edx ;"
+ "movl $0,%%eax ;"
+ "cpuid ;"
+ "pop %%edx ;"
+ "pop %%ecx ;"
+ "pop %%ebx ;"
+ "pop %%eax" : /* no outputs */ : /* no inputs */ );
+}
+
+static int r128_do_cleanup_cce(drm_device_t *dev)
+{
+ if (dev->dev_private) {
+ drm_r128_private_t *dev_priv = dev->dev_private;
+
+ if (!dev_priv->is_pci) {
+ DO_REMAPFREE(dev_priv->agp_ring);
+ DO_REMAPFREE(dev_priv->agp_read_ptr);
+ DO_REMAPFREE(dev_priv->agp_vertbufs);
+ DO_REMAPFREE(dev_priv->agp_indbufs);
+ DO_REMAPFREE(dev_priv->agp_textures);
+ }
+
+ drm_free(dev->dev_private, sizeof(drm_r128_private_t),
+ DRM_MEM_DRIVER);
+ dev->dev_private = NULL;
+ }
+
+ return 0;
+}
+
+static int r128_do_init_cce(drm_device_t *dev, drm_r128_init_t *init)
+{
+ drm_r128_private_t *dev_priv;
+ int i;
+
+ dev_priv = drm_alloc(sizeof(drm_r128_private_t), DRM_MEM_DRIVER);
+ if (dev_priv == NULL) return -ENOMEM;
+ dev->dev_private = (void *)dev_priv;
+
+ memset(dev_priv, 0, sizeof(drm_r128_private_t));
+
+ dev_priv->is_pci = init->is_pci;
+
+ dev_priv->usec_timeout = init->usec_timeout;
+ if (dev_priv->usec_timeout < 1 ||
+ dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT) {
+ drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
+ dev->dev_private = NULL;
+ return -EINVAL;
+ }
+
+ dev_priv->cce_mode = init->cce_mode;
+ dev_priv->cce_fifo_size = init->cce_fifo_size;
+ dev_priv->cce_is_bm_mode =
+ ((init->cce_mode == R128_PM4_192BM) ||
+ (init->cce_mode == R128_PM4_128BM_64INDBM) ||
+ (init->cce_mode == R128_PM4_64BM_128INDBM) ||
+ (init->cce_mode == R128_PM4_64BM_64VCBM_64INDBM));
+ dev_priv->cce_secure = init->cce_secure;
+
+ if (dev_priv->cce_is_bm_mode && dev_priv->is_pci) {
+ drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
+ dev->dev_private = NULL;
+ return -EINVAL;
+ }
+
+ for (i = 0; i < dev->map_count; i++) {
+ if (dev->maplist[i]->type == _DRM_SHM) {
+ dev_priv->sarea = dev->maplist[i];
+ break;
+ }
+ }
+
+ DO_FIND_MAP(dev_priv->fb, init->fb_offset);
+ if (!dev_priv->is_pci) {
+ DO_FIND_MAP(dev_priv->agp_ring, init->agp_ring_offset);
+ DO_FIND_MAP(dev_priv->agp_read_ptr, init->agp_read_ptr_offset);
+ DO_FIND_MAP(dev_priv->agp_vertbufs, init->agp_vertbufs_offset);
+ DO_FIND_MAP(dev_priv->agp_indbufs, init->agp_indbufs_offset);
+ DO_FIND_MAP(dev_priv->agp_textures, init->agp_textures_offset);
+ }
+ DO_FIND_MAP(dev_priv->mmio, init->mmio_offset);
+
+ dev_priv->sarea_priv =
+ (drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle +
+ init->sarea_priv_offset);
+
+ if (!dev_priv->is_pci) {
+ DO_REMAP(dev_priv->agp_ring);
+ DO_REMAP(dev_priv->agp_read_ptr);
+ DO_REMAP(dev_priv->agp_vertbufs);
+#if 0
+ DO_REMAP(dev_priv->agp_indirectbufs);
+ DO_REMAP(dev_priv->agp_textures);
+#endif
+
+ dev_priv->ring_size = init->ring_size;
+ dev_priv->ring_sizel2qw = drm_order(init->ring_size/8);
+ dev_priv->ring_entries = init->ring_size/sizeof(u32);
+ dev_priv->ring_read_ptr = ((__volatile__ u32 *)
+ dev_priv->agp_read_ptr->handle);
+ dev_priv->ring_start = (u32 *)dev_priv->agp_ring->handle;
+ dev_priv->ring_end = ((u32 *)dev_priv->agp_ring->handle
+ + dev_priv->ring_entries);
+ }
+
+ dev_priv->submit_age = 0;
+ R128_WRITE(R128_VB_AGE_REG, dev_priv->submit_age);
+
+ return 0;
+}
+
+int r128_init_cce(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_r128_init_t init;
+
+ copy_from_user_ret(&init, (drm_r128_init_t *)arg, sizeof(init),
+ -EFAULT);
+
+ switch (init.func) {
+ case R128_INIT_CCE:
+ return r128_do_init_cce(dev, &init);
+ case R128_CLEANUP_CCE:
+ return r128_do_cleanup_cce(dev);
+ }
+
+ return -EINVAL;
+}
+
+static void r128_mark_vertbufs_done(drm_device_t *dev)
+{
+ drm_device_dma_t *dma = dev->dma;
+ int i;
+
+ for (i = 0; i < dma->buf_count; i++) {
+ drm_buf_t *buf = dma->buflist[i];
+ drm_r128_buf_priv_t *buf_priv = buf->dev_private;
+ buf_priv->age = 0;
+ }
+}
+
+static int r128_do_pixcache_flush(drm_device_t *dev)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ u32 tmp;
+ int i;
+
+ tmp = R128_READ(R128_PC_NGUI_CTLSTAT) | R128_PC_FLUSH_ALL;
+ R128_WRITE(R128_PC_NGUI_CTLSTAT, tmp);
+
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY))
+ return 0;
+ udelay(1);
+ }
+
+ return -EBUSY;
+}
+
+static int r128_do_wait_for_fifo(drm_device_t *dev, int entries)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ int i;
+
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ int slots = R128_READ(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK;
+ if (slots >= entries) return 0;
+ udelay(1);
+ }
+ return -EBUSY;
+}
+
+static int r128_do_wait_for_idle(drm_device_t *dev)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ int i, ret;
+
+ if (!(ret = r128_do_wait_for_fifo(dev, 64))) return ret;
+
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (!(R128_READ(R128_GUI_STAT) & R128_GUI_ACTIVE)) {
+ (void)r128_do_pixcache_flush(dev);
+ return 0;
+ }
+ udelay(1);
+ }
+ return -EBUSY;
+}
+
+int r128_do_engine_reset(drm_device_t *dev)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ u32 clock_cntl_index, mclk_cntl, gen_reset_cntl;
+
+ (void)r128_do_pixcache_flush(dev);
+
+ clock_cntl_index = R128_READ(R128_CLOCK_CNTL_INDEX);
+ mclk_cntl = R128_READ_PLL(dev, R128_MCLK_CNTL);
+
+ R128_WRITE_PLL(R128_MCLK_CNTL,
+ mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CPP);
+
+ gen_reset_cntl = R128_READ(R128_GEN_RESET_CNTL);
+
+ R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI);
+ (void)R128_READ(R128_GEN_RESET_CNTL);
+ R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI);
+ (void)R128_READ(R128_GEN_RESET_CNTL);
+
+ R128_WRITE_PLL(R128_MCLK_CNTL, mclk_cntl);
+ R128_WRITE(R128_CLOCK_CNTL_INDEX, clock_cntl_index);
+ R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl);
+
+ /* For CCE ring buffer only */
+ if (dev_priv->cce_is_bm_mode) {
+ R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0);
+ R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0);
+ *dev_priv->ring_read_ptr = 0;
+ dev_priv->sarea_priv->ring_write = 0;
+ }
+
+ /* Reset the CCE mode */
+ (void)r128_do_wait_for_idle(dev);
+ R128_WRITE(R128_PM4_BUFFER_CNTL,
+ dev_priv->cce_mode | dev_priv->ring_sizel2qw);
+ (void)R128_READ(R128_PM4_BUFFER_ADDR); /* as per the sample code */
+ R128_WRITE(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN);
+
+ r128_mark_vertbufs_done(dev);
+ return 0;
+}
+
+int r128_eng_reset(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ||
+ dev->lock.pid != current->pid) {
+ DRM_ERROR("r128_eng_reset called without holding the lock\n");
+ return -EINVAL;
+ }
+
+ return r128_do_engine_reset(dev);
+}
+
+static int r128_do_engine_flush(drm_device_t *dev)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ u32 tmp;
+
+ tmp = R128_READ(R128_PM4_BUFFER_DL_WPTR);
+ R128_WRITE(R128_PM4_BUFFER_DL_WPTR, tmp | R128_PM4_BUFFER_DL_DONE);
+
+ return 0;
+}
+
+int r128_eng_flush(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ||
+ dev->lock.pid != current->pid) {
+ DRM_ERROR("r128_eng_flush called without holding the lock\n");
+ return -EINVAL;
+ }
+
+ return r128_do_engine_flush(dev);
+}
+
+static int r128_do_cce_wait_for_fifo(drm_device_t *dev, int entries)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ int i;
+
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ int slots = R128_READ(R128_PM4_STAT) & R128_PM4_FIFOCNT_MASK;
+ if (slots >= entries) return 0;
+ udelay(1);
+ }
+ return -EBUSY;
+}
+
+int r128_do_cce_wait_for_idle(drm_device_t *dev)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ int i;
+
+ if (dev_priv->cce_is_bm_mode) {
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (*dev_priv->ring_read_ptr == dev_priv->sarea_priv->ring_write) {
+ int pm4stat = R128_READ(R128_PM4_STAT);
+ if ((pm4stat & R128_PM4_FIFOCNT_MASK) >= dev_priv->cce_fifo_size &&
+ !(pm4stat & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) {
+ return r128_do_pixcache_flush(dev);
+ }
+ }
+ udelay(1);
+ }
+ return -EBUSY;
+ } else {
+ int ret = r128_do_cce_wait_for_fifo(dev, dev_priv->cce_fifo_size);
+ if (ret < 0) return ret;
+
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ int pm4stat = R128_READ(R128_PM4_STAT);
+ if (!(pm4stat & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) {
+ return r128_do_pixcache_flush(dev);
+ }
+ udelay(1);
+ }
+ return -EBUSY;
+ }
+}
+
+int r128_cce_idle(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ||
+ dev->lock.pid != current->pid) {
+ DRM_ERROR("r128_wait_idle called without holding the lock\n");
+ return -EINVAL;
+ }
+
+ return r128_do_cce_wait_for_idle(dev);
+}
+
+static int r128_submit_packets_ring_secure(drm_device_t *dev,
+ u32 *commands, int *count)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ int write = dev_priv->sarea_priv->ring_write;
+ int *write_ptr = dev_priv->ring_start + write;
+ int c = *count;
+ u32 tmp = 0;
+ int psize = 0;
+ int writing = 1;
+ int timeout;
+
+ while (c > 0) {
+ tmp = *commands++;
+ if (!psize) {
+ writing = 1;
+
+ if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET0) {
+ if ((tmp & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2)) {
+ if ((tmp & R128_CCE_PACKET0_REG_MASK) !=
+ (R128_PM4_VC_FPU_SETUP >> 2)) {
+ writing = 0;
+ }
+ }
+ psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
+ } else if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET1) {
+ if ((tmp & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2)) {
+ if ((tmp & R128_CCE_PACKET1_REG0_MASK) !=
+ (R128_PM4_VC_FPU_SETUP >> 2)) {
+ writing = 0;
+ }
+ } else if ((tmp & R128_CCE_PACKET1_REG1_MASK) <=
+ (0x1004 << 9)) {
+ if ((tmp & R128_CCE_PACKET1_REG1_MASK) !=
+ (R128_PM4_VC_FPU_SETUP << 9)) {
+ writing = 0;
+ }
+ }
+ psize = 3;
+ } else {
+ psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
+ }
+ }
+ psize--;
+
+ if (writing) {
+ write++;
+ *write_ptr++ = tmp;
+ }
+ if (write >= dev_priv->ring_entries) {
+ write = 0;
+ write_ptr = dev_priv->ring_start;
+ }
+ timeout = 0;
+ while (write == *dev_priv->ring_read_ptr) {
+ (void)R128_READ(R128_PM4_BUFFER_DL_RPTR);
+ if (timeout++ >= dev_priv->usec_timeout)
+ return -EBUSY;
+ udelay(1);
+ }
+ c--;
+ }
+
+ if (write < 32)
+ memcpy(dev_priv->ring_end,
+ dev_priv->ring_start,
+ write * sizeof(u32));
+
+ /* Make sure WC cache has been flushed */
+ r128_flush_write_combine();
+
+ dev_priv->sarea_priv->ring_write = write;
+ R128_WRITE(R128_PM4_BUFFER_DL_WPTR, write);
+
+ *count = 0;
+
+ return 0;
+}
+
+static int r128_submit_packets_pio_secure(drm_device_t *dev,
+ u32 *commands, int *count)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ u32 tmp = 0;
+ int psize = 0;
+ int writing = 1;
+ int addr = R128_PM4_FIFO_DATA_EVEN;
+ int ret;
+
+ while (*count > 0) {
+ tmp = *commands++;
+ if (!psize) {
+ writing = 1;
+
+ if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET0) {
+ if ((tmp & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2)) {
+ if ((tmp & R128_CCE_PACKET0_REG_MASK) !=
+ (R128_PM4_VC_FPU_SETUP >> 2)) {
+ writing = 0;
+ }
+ }
+ psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
+ } else if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET1) {
+ if ((tmp & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2)) {
+ if ((tmp & R128_CCE_PACKET1_REG0_MASK) !=
+ (R128_PM4_VC_FPU_SETUP >> 2)) {
+ writing = 0;
+ }
+ } else if ((tmp & R128_CCE_PACKET1_REG1_MASK) <=
+ (0x1004 << 9)) {
+ if ((tmp & R128_CCE_PACKET1_REG1_MASK) !=
+ (R128_PM4_VC_FPU_SETUP << 9)) {
+ writing = 0;
+ }
+ }
+ psize = 3;
+ } else {
+ psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
+ }
+ }
+ psize--;
+
+ if (writing) {
+ if ((ret = r128_do_cce_wait_for_fifo(dev, 1)) < 0)
+ return ret;
+ R128_WRITE(addr, tmp);
+ addr ^= 0x0004;
+ }
+
+ *count -= 1;
+ }
+
+ if (addr == R128_PM4_FIFO_DATA_ODD) {
+ if ((ret = r128_do_cce_wait_for_fifo(dev, 1)) < 0) return ret;
+ R128_WRITE(addr, R128_CCE_PACKET2);
+ }
+
+ return 0;
+}
+
+static int r128_submit_packets_ring(drm_device_t *dev,
+ u32 *commands, int *count)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ int write = dev_priv->sarea_priv->ring_write;
+ int *write_ptr = dev_priv->ring_start + write;
+ int c = *count;
+ int timeout;
+
+ while (c > 0) {
+ write++;
+ *write_ptr++ = *commands++;
+ if (write >= dev_priv->ring_entries) {
+ write = 0;
+ write_ptr = dev_priv->ring_start;
+ }
+ timeout = 0;
+ while (write == *dev_priv->ring_read_ptr) {
+ (void)R128_READ(R128_PM4_BUFFER_DL_RPTR);
+ if (timeout++ >= dev_priv->usec_timeout)
+ return -EBUSY;
+ udelay(1);
+ }
+ c--;
+ }
+
+ if (write < 32)
+ memcpy(dev_priv->ring_end,
+ dev_priv->ring_start,
+ write * sizeof(u32));
+
+ /* Make sure WC cache has been flushed */
+ r128_flush_write_combine();
+
+ dev_priv->sarea_priv->ring_write = write;
+ R128_WRITE(R128_PM4_BUFFER_DL_WPTR, write);
+
+ *count = 0;
+
+ return 0;
+}
+
+static int r128_submit_packets_pio(drm_device_t *dev,
+ u32 *commands, int *count)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ int ret;
+
+ while (*count > 1) {
+ if ((ret = r128_do_cce_wait_for_fifo(dev, 2)) < 0) return ret;
+ R128_WRITE(R128_PM4_FIFO_DATA_EVEN, *commands++);
+ R128_WRITE(R128_PM4_FIFO_DATA_ODD, *commands++);
+ *count -= 2;
+ }
+
+ if (*count) {
+ if ((ret = r128_do_cce_wait_for_fifo(dev, 2)) < 0) return ret;
+ R128_WRITE(R128_PM4_FIFO_DATA_EVEN, *commands++);
+ R128_WRITE(R128_PM4_FIFO_DATA_ODD, R128_CCE_PACKET2);
+ *count = 0;
+ }
+
+ return 0;
+}
+
+static int r128_do_submit_packets(drm_device_t *dev, u32 *buffer, int count)
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ int c = count;
+ int ret;
+
+ if (dev_priv->cce_is_bm_mode) {
+ int left = 0;
+
+ if (c >= dev_priv->ring_entries) {
+ c = dev_priv->ring_entries-1;
+ left = count - c;
+ }
+
+ /* Since this is only used by the kernel we can use the
+ insecure ring buffer submit packet routine */
+ ret = r128_submit_packets_ring(dev, buffer, &c);
+
+ c += left;
+ } else {
+ /* Since this is only used by the kernel we can use the
+ insecure PIO submit packet routine */
+ ret = r128_submit_packets_pio(dev, buffer, &c);
+ }
+
+ if (ret < 0) return ret;
+ else return c;
+}
+
+int r128_submit_pkt(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_packet_t packet;
+ u32 *buffer;
+ int c;
+ int size;
+ int ret = 0;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ||
+ dev->lock.pid != current->pid) {
+ DRM_ERROR("r128_submit_pkt called without holding the lock\n");
+ return -EINVAL;
+ }
+
+ copy_from_user_ret(&packet, (drm_r128_packet_t *)arg, sizeof(packet),
+ -EFAULT);
+
+ c = packet.count;
+ size = c * sizeof(*buffer);
+
+ if (dev_priv->cce_is_bm_mode) {
+ int left = 0;
+
+ if (c >= dev_priv->ring_entries) {
+ c = dev_priv->ring_entries-1;
+ size = c * sizeof(*buffer);
+ left = packet.count - c;
+ }
+
+ if ((buffer = kmalloc(size, 0)) == NULL) return -ENOMEM;
+ copy_from_user_ret(buffer, packet.buffer, size, -EFAULT);
+
+ if (dev_priv->cce_secure)
+ ret = r128_submit_packets_ring_secure(dev, buffer, &c);
+ else
+ ret = r128_submit_packets_ring(dev, buffer, &c);
+
+ c += left;
+ } else {
+ if ((buffer = kmalloc(size, 0)) == NULL) return -ENOMEM;
+ copy_from_user_ret(buffer, packet.buffer, size, -EFAULT);
+
+ if (dev_priv->cce_secure)
+ ret = r128_submit_packets_pio_secure(dev, buffer, &c);
+ else
+ ret = r128_submit_packets_pio(dev, buffer, &c);
+ }
+
+ kfree(buffer);
+
+ packet.count = c;
+ copy_to_user_ret((drm_r128_packet_t *)arg, &packet, sizeof(packet),
+ -EFAULT);
+
+ if (ret) return ret;
+ else if (c > 0) return -EAGAIN;
+
+ return 0;
+}
+
+static int r128_send_vertbufs(drm_device_t *dev, drm_r128_vertex_t *v)
+{
+ drm_device_dma_t *dma = dev->dma;
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_buf_priv_t *buf_priv;
+ drm_buf_t *buf;
+ int i, ret;
+ u32 cce[2];
+
+ /* Make sure we have valid data */
+ for (i = 0; i < v->send_count; i++) {
+ int idx = v->send_indices[i];
+
+ if (idx < 0 || idx >= dma->buf_count) {
+ DRM_ERROR("Index %d (of %d max)\n",
+ idx, dma->buf_count - 1);
+ return -EINVAL;
+ }
+ buf = dma->buflist[idx];
+ if (buf->pid != current->pid) {
+ DRM_ERROR("Process %d using buffer owned by %d\n",
+ current->pid, buf->pid);
+ return -EINVAL;
+ }
+ if (buf->pending) {
+ DRM_ERROR("Sending pending buffer:"
+ " buffer %d, offset %d\n",
+ v->send_indices[i], i);
+ return -EINVAL;
+ }
+ }
+
+ /* Wait for idle, if we've wrapped to make sure that all pending
+ buffers have been processed */
+ if (dev_priv->submit_age == R128_MAX_VBUF_AGE) {
+ if ((ret = r128_do_cce_wait_for_idle(dev)) < 0) return ret;
+ dev_priv->submit_age = 0;
+ r128_mark_vertbufs_done(dev);
+ }
+
+ /* Make sure WC cache has been flushed (if in PIO mode) */
+ if (!dev_priv->cce_is_bm_mode) r128_flush_write_combine();
+
+ /* FIXME: Add support for sending vertex buffer to the CCE here
+ instead of in client code. The v->prim holds the primitive
+ type that should be drawn. Loop over the list buffers in
+ send_indices[] and submit a packet for each VB.
+
+ This will require us to loop over the clip rects here as
+ well, which implies that we extend the kernel driver to allow
+ cliprects to be stored here. Note that the cliprects could
+ possibly come from the X server instead of the client, but
+ this will require additional changes to the DRI to allow for
+ this optimization. */
+
+ /* Submit a CCE packet that writes submit_age to R128_VB_AGE_REG */
+ cce[0] = R128CCE0(R128_CCE_PACKET0, R128_VB_AGE_REG, 0);
+ cce[1] = dev_priv->submit_age;
+ if ((ret = r128_do_submit_packets(dev, cce, 2)) < 0) {
+ /* Until we add support for sending VBs to the CCE in
+ this routine, we can recover from this error. After
+ we add that support, we won't be able to easily
+ recover, so we will probably have to implement
+ another mechanism for handling timeouts from packets
+ submitted directly by the kernel. */
+ return ret;
+ }
+
+ /* Now that the submit packet request has succeeded, we can mark
+ the buffers as pending */
+ for (i = 0; i < v->send_count; i++) {
+ buf = dma->buflist[v->send_indices[i]];
+ buf->pending = 1;
+
+ buf_priv = buf->dev_private;
+ buf_priv->age = dev_priv->submit_age;
+ }
+
+ dev_priv->submit_age++;
+
+ return 0;
+}
+
+static drm_buf_t *r128_freelist_get(drm_device_t *dev)
+{
+ drm_device_dma_t *dma = dev->dma;
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_buf_priv_t *buf_priv;
+ drm_buf_t *buf;
+ int i, t;
+
+ /* FIXME: Optimize -- use freelist code */
+
+ for (i = 0; i < dma->buf_count; i++) {
+ buf = dma->buflist[i];
+ buf_priv = buf->dev_private;
+ if (buf->pid == 0) return buf;
+ }
+
+ for (t = 0; t < dev_priv->usec_timeout; t++) {
+ u32 done_age = R128_READ(R128_VB_AGE_REG);
+
+ for (i = 0; i < dma->buf_count; i++) {
+ buf = dma->buflist[i];
+ buf_priv = buf->dev_private;
+ if (buf->pending && buf_priv->age <= done_age) {
+ /* The buffer has been processed, so it
+ can now be used */
+ buf->pending = 0;
+ return buf;
+ }
+ }
+ udelay(1);
+ }
+
+ return NULL;
+}
+
+
+static int r128_get_vertbufs(drm_device_t *dev, drm_r128_vertex_t *v)
+{
+ drm_buf_t *buf;
+ int i;
+
+ for (i = v->granted_count; i < v->request_count; i++) {
+ buf = r128_freelist_get(dev);
+ if (!buf) break;
+ buf->pid = current->pid;
+ copy_to_user_ret(&v->request_indices[i],
+ &buf->idx,
+ sizeof(buf->idx),
+ -EFAULT);
+ copy_to_user_ret(&v->request_sizes[i],
+ &buf->total,
+ sizeof(buf->total),
+ -EFAULT);
+ ++v->granted_count;
+ }
+ return 0;
+}
+
+int r128_vertex_buf(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_device_dma_t *dma = dev->dma;
+ int retcode = 0;
+ drm_r128_vertex_t v;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ||
+ dev->lock.pid != current->pid) {
+ DRM_ERROR("r128_vertex_buf called without holding the lock\n");
+ return -EINVAL;
+ }
+
+ if (!dev_priv || dev_priv->is_pci) {
+ DRM_ERROR("r128_vertex_buf called with a PCI card\n");
+ return -EINVAL;
+ }
+
+ copy_from_user_ret(&v, (drm_r128_vertex_t *)arg, sizeof(v), -EFAULT);
+ DRM_DEBUG("%d: %d send, %d req\n",
+ current->pid, v.send_count, v.request_count);
+
+ if (v.send_count < 0 || v.send_count > dma->buf_count) {
+ DRM_ERROR("Process %d trying to send %d buffers (of %d max)\n",
+ current->pid, v.send_count, dma->buf_count);
+ return -EINVAL;
+ }
+ if (v.request_count < 0 || v.request_count > dma->buf_count) {
+ DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
+ current->pid, v.request_count, dma->buf_count);
+ return -EINVAL;
+ }
+
+ if (v.send_count) {
+ retcode = r128_send_vertbufs(dev, &v);
+ }
+
+ v.granted_count = 0;
+
+ if (!retcode && v.request_count) {
+ retcode = r128_get_vertbufs(dev, &v);
+ }
+
+ DRM_DEBUG("%d returning, granted = %d\n",
+ current->pid, v.granted_count);
+ copy_to_user_ret((drm_r128_vertex_t *)arg, &v, sizeof(v), -EFAULT);
+
+ return retcode;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h
new file mode 100644
index 000000000..fa90d72db
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h
@@ -0,0 +1,111 @@
+/* r128_drm.h -- Public header for the r128 driver -*- linux-c -*-
+ * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com
+ *
+ * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $XFree86$
+ */
+
+#ifndef _R128_DRM_H_
+#define _R128_DRM_H_
+
+/* WARNING: If you change any of these defines, make sure to change the
+ * defines in the Xserver file (xf86drmR128.h)
+ */
+typedef struct drm_r128_init {
+ enum {
+ R128_INIT_CCE = 0x01,
+ R128_CLEANUP_CCE = 0x02
+ } func;
+ int sarea_priv_offset;
+ int is_pci;
+ int cce_mode;
+ int cce_fifo_size;
+ int cce_secure;
+ int ring_size;
+ int usec_timeout;
+
+ int fb_offset;
+ int agp_ring_offset;
+ int agp_read_ptr_offset;
+ int agp_vertbufs_offset;
+ int agp_indbufs_offset;
+ int agp_textures_offset;
+ int mmio_offset;
+} drm_r128_init_t;
+
+typedef struct drm_r128_packet {
+ unsigned long *buffer;
+ int count;
+ int flags;
+} drm_r128_packet_t;
+
+typedef enum drm_r128_prim {
+ _DRM_R128_PRIM_NONE = 0x0001,
+ _DRM_R128_PRIM_POINT = 0x0002,
+ _DRM_R128_PRIM_LINE = 0x0004,
+ _DRM_R128_PRIM_POLY_LINE = 0x0008,
+ _DRM_R128_PRIM_TRI_LIST = 0x0010,
+ _DRM_R128_PRIM_TRI_FAN = 0x0020,
+ _DRM_R128_PRIM_TRI_STRIP = 0x0040,
+ _DRM_R128_PRIM_TRI_TYPE2 = 0x0080
+} drm_r128_prim_t;
+
+typedef struct drm_r128_vertex {
+ /* Indices here refer to the offset into
+ buflist in drm_buf_get_t. */
+ int send_count; /* Number of buffers to send */
+ int *send_indices; /* List of handles to buffers */
+ int *send_sizes; /* Lengths of data to send */
+ drm_r128_prim_t prim; /* Primitive type */
+ int request_count; /* Number of buffers requested */
+ int *request_indices; /* Buffer information */
+ int *request_sizes;
+ int granted_count; /* Number of buffers granted */
+} drm_r128_vertex_t;
+
+/* WARNING: If you change any of these defines, make sure to change the
+ * defines in the Xserver file (r128_sarea.h)
+ */
+#define R128_LOCAL_TEX_HEAP 0
+#define R128_AGP_TEX_HEAP 1
+#define R128_NR_TEX_HEAPS 2
+#define R128_NR_TEX_REGIONS 64
+#define R128_LOG_TEX_GRANULARITY 16
+
+typedef struct drm_tex_region {
+ unsigned char next, prev;
+ unsigned char in_use;
+ int age;
+} drm_tex_region_t;
+
+typedef struct drm_r128_sarea {
+ drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1];
+ int tex_age[R128_NR_TEX_HEAPS];
+ int ctx_owner;
+ int ring_write;
+} drm_r128_sarea_t;
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c
new file mode 100644
index 000000000..45ade1def
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c
@@ -0,0 +1,737 @@
+/* r128_drv.c -- ATI Rage 128 driver -*- linux-c -*-
+ * Created: Mon Dec 13 09:47:27 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com>
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $XFree86$
+ *
+ */
+
+#define EXPORT_SYMTAB
+#include "drmP.h"
+#include "r128_drv.h"
+EXPORT_SYMBOL(r128_init);
+EXPORT_SYMBOL(r128_cleanup);
+
+#define R128_NAME "r128"
+#define R128_DESC "r128"
+#define R128_DATE "20000422"
+#define R128_MAJOR 0
+#define R128_MINOR 0
+#define R128_PATCHLEVEL 5
+
+static drm_device_t r128_device;
+drm_ctx_t r128_res_ctx;
+
+static struct file_operations r128_fops = {
+ open: r128_open,
+ flush: drm_flush,
+ release: r128_release,
+ ioctl: r128_ioctl,
+ mmap: drm_mmap,
+ read: drm_read,
+ fasync: drm_fasync,
+ poll: drm_poll,
+};
+
+static struct miscdevice r128_misc = {
+ minor: MISC_DYNAMIC_MINOR,
+ name: R128_NAME,
+ fops: &r128_fops,
+};
+
+static drm_ioctl_desc_t r128_ioctls[] = {
+ [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { r128_version, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_busid, 0, 1 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_block, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { r128_addbufs, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { r128_mapbufs, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, 1, 0 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { r128_addctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { r128_rmctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { r128_modctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { r128_getctx, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { r128_switchctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { r128_newctx, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { r128_resctx, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { r128_lock, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { r128_unlock, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 },
+
+#ifdef DRM_AGP
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
+#endif
+
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_init_cce, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_eng_reset, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_FLUSH)] = { r128_eng_flush, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_submit_pkt, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_CCEIDL)] = { r128_cce_idle, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_vertex_buf, 1, 0 },
+};
+#define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls)
+
+#ifdef MODULE
+int init_module(void);
+void cleanup_module(void);
+static char *r128 = NULL;
+
+MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas.");
+MODULE_DESCRIPTION("r128");
+MODULE_PARM(r128, "s");
+
+/* init_module is called when insmod is used to load the module */
+
+int init_module(void)
+{
+ return r128_init();
+}
+
+/* cleanup_module is called when rmmod is used to unload the module */
+
+void cleanup_module(void)
+{
+ r128_cleanup();
+}
+#endif
+
+#ifndef MODULE
+/* r128_setup is called by the kernel to parse command-line options passed
+ * via the boot-loader (e.g., LILO). It calls the insmod option routine,
+ * drm_parse_drm.
+ *
+ * This is not currently supported, since it requires changes to
+ * linux/init/main.c. */
+
+
+void __init r128_setup(char *str, int *ints)
+{
+ if (ints[0] != 0) {
+ DRM_ERROR("Illegal command line format, ignored\n");
+ return;
+ }
+ drm_parse_options(str);
+}
+#endif
+
+static int r128_setup(drm_device_t *dev)
+{
+ int i;
+
+ atomic_set(&dev->ioctl_count, 0);
+ atomic_set(&dev->vma_count, 0);
+ dev->buf_use = 0;
+ atomic_set(&dev->buf_alloc, 0);
+
+ drm_dma_setup(dev);
+
+ atomic_set(&dev->total_open, 0);
+ atomic_set(&dev->total_close, 0);
+ atomic_set(&dev->total_ioctl, 0);
+ atomic_set(&dev->total_irq, 0);
+ atomic_set(&dev->total_ctx, 0);
+ atomic_set(&dev->total_locks, 0);
+ atomic_set(&dev->total_unlocks, 0);
+ atomic_set(&dev->total_contends, 0);
+ atomic_set(&dev->total_sleeps, 0);
+
+ for (i = 0; i < DRM_HASH_SIZE; i++) {
+ dev->magiclist[i].head = NULL;
+ dev->magiclist[i].tail = NULL;
+ }
+ dev->maplist = NULL;
+ dev->map_count = 0;
+ dev->vmalist = NULL;
+ dev->lock.hw_lock = NULL;
+ init_waitqueue_head(&dev->lock.lock_queue);
+ dev->queue_count = 0;
+ dev->queue_reserved = 0;
+ dev->queue_slots = 0;
+ dev->queuelist = NULL;
+ dev->irq = 0;
+ dev->context_flag = 0;
+ dev->interrupt_flag = 0;
+ dev->dma_flag = 0;
+ dev->last_context = 0;
+ dev->last_switch = 0;
+ dev->last_checked = 0;
+ init_timer(&dev->timer);
+ init_waitqueue_head(&dev->context_wait);
+
+ dev->ctx_start = 0;
+ dev->lck_start = 0;
+
+ dev->buf_rp = dev->buf;
+ dev->buf_wp = dev->buf;
+ dev->buf_end = dev->buf + DRM_BSZ;
+ dev->buf_async = NULL;
+ init_waitqueue_head(&dev->buf_readers);
+ init_waitqueue_head(&dev->buf_writers);
+
+ r128_res_ctx.handle=-1;
+
+ DRM_DEBUG("\n");
+
+ /* The kernel's context could be created here, but is now created
+ in drm_dma_enqueue. This is more resource-efficient for
+ hardware that does not do DMA, but may mean that
+ drm_select_queue fails between the time the interrupt is
+ initialized and the time the queues are initialized. */
+
+ return 0;
+}
+
+
+static int r128_takedown(drm_device_t *dev)
+{
+ int i;
+ drm_magic_entry_t *pt, *next;
+ drm_map_t *map;
+ drm_vma_entry_t *vma, *vma_next;
+
+ DRM_DEBUG("\n");
+
+ down(&dev->struct_sem);
+ del_timer(&dev->timer);
+
+ if (dev->devname) {
+ drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
+ dev->devname = NULL;
+ }
+
+ if (dev->unique) {
+ drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
+ dev->unique = NULL;
+ dev->unique_len = 0;
+ }
+ /* Clear pid list */
+ for (i = 0; i < DRM_HASH_SIZE; i++) {
+ for (pt = dev->magiclist[i].head; pt; pt = next) {
+ next = pt->next;
+ drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
+ }
+ dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
+ }
+
+#ifdef DRM_AGP
+ /* Clear AGP information */
+ if (dev->agp) {
+ drm_agp_mem_t *entry;
+ drm_agp_mem_t *nexte;
+
+ /* Remove AGP resources, but leave dev->agp
+ intact until r128_cleanup is called. */
+ for (entry = dev->agp->memory; entry; entry = nexte) {
+ nexte = entry->next;
+ if (entry->bound) drm_unbind_agp(entry->memory);
+ drm_free_agp(entry->memory, entry->pages);
+ drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+ }
+ dev->agp->memory = NULL;
+
+ if (dev->agp->acquired && drm_agp.release)
+ (*drm_agp.release)();
+
+ dev->agp->acquired = 0;
+ dev->agp->enabled = 0;
+ }
+#endif
+
+ /* Clear vma list (only built for debugging) */
+ if (dev->vmalist) {
+ for (vma = dev->vmalist; vma; vma = vma_next) {
+ vma_next = vma->next;
+ drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
+ }
+ dev->vmalist = NULL;
+ }
+
+ /* Clear map area and mtrr information */
+ if (dev->maplist) {
+ for (i = 0; i < dev->map_count; i++) {
+ map = dev->maplist[i];
+ switch (map->type) {
+ case _DRM_REGISTERS:
+ case _DRM_FRAME_BUFFER:
+#ifdef CONFIG_MTRR
+ if (map->mtrr >= 0) {
+ int retcode;
+ retcode = mtrr_del(map->mtrr,
+ map->offset,
+ map->size);
+ DRM_DEBUG("mtrr_del = %d\n", retcode);
+ }
+#endif
+ drm_ioremapfree(map->handle, map->size);
+ break;
+ case _DRM_SHM:
+ drm_free_pages((unsigned long)map->handle,
+ drm_order(map->size)
+ - PAGE_SHIFT,
+ DRM_MEM_SAREA);
+ break;
+ case _DRM_AGP:
+ /* Do nothing here, because this is all
+ handled in the AGP/GART driver. */
+ break;
+ }
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ }
+ drm_free(dev->maplist,
+ dev->map_count * sizeof(*dev->maplist),
+ DRM_MEM_MAPS);
+ dev->maplist = NULL;
+ dev->map_count = 0;
+ }
+
+ drm_dma_takedown(dev);
+
+ dev->queue_count = 0;
+ if (dev->lock.hw_lock) {
+ dev->lock.hw_lock = NULL; /* SHM removed */
+ dev->lock.pid = 0;
+ wake_up_interruptible(&dev->lock.lock_queue);
+ }
+ up(&dev->struct_sem);
+
+ return 0;
+}
+
+/* r128_init is called via init_module at module load time, or via
+ * linux/init/main.c (this is not currently supported). */
+
+int r128_init(void)
+{
+ int retcode;
+ drm_device_t *dev = &r128_device;
+
+ DRM_DEBUG("\n");
+
+ memset((void *)dev, 0, sizeof(*dev));
+ dev->count_lock = SPIN_LOCK_UNLOCKED;
+ sema_init(&dev->struct_sem, 1);
+
+#ifdef MODULE
+ drm_parse_options(r128);
+#endif
+
+ if ((retcode = misc_register(&r128_misc))) {
+ DRM_ERROR("Cannot register \"%s\"\n", R128_NAME);
+ return retcode;
+ }
+ dev->device = MKDEV(MISC_MAJOR, r128_misc.minor);
+ dev->name = R128_NAME;
+
+ drm_mem_init();
+ drm_proc_init(dev);
+
+#ifdef DRM_AGP
+ dev->agp = drm_agp_init();
+
+#ifdef CONFIG_MTRR
+ dev->agp->agp_mtrr = mtrr_add(dev->agp->agp_info.aper_base,
+ dev->agp->agp_info.aper_size*1024*1024,
+ MTRR_TYPE_WRCOMB,
+ 1);
+#endif
+#endif
+
+ if((retcode = drm_ctxbitmap_init(dev))) {
+ DRM_ERROR("Cannot allocate memory for context bitmap.\n");
+ drm_proc_cleanup();
+ misc_deregister(&r128_misc);
+ r128_takedown(dev);
+ return retcode;
+ }
+
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+ R128_NAME,
+ R128_MAJOR,
+ R128_MINOR,
+ R128_PATCHLEVEL,
+ R128_DATE,
+ r128_misc.minor);
+
+ return 0;
+}
+
+/* r128_cleanup is called via cleanup_module at module unload time. */
+
+void r128_cleanup(void)
+{
+ drm_device_t *dev = &r128_device;
+
+ DRM_DEBUG("\n");
+
+ drm_proc_cleanup();
+ if (misc_deregister(&r128_misc)) {
+ DRM_ERROR("Cannot unload module\n");
+ } else {
+ DRM_INFO("Module unloaded\n");
+ }
+ drm_ctxbitmap_cleanup(dev);
+ r128_takedown(dev);
+#ifdef DRM_AGP
+ if (dev->agp) {
+ /* FIXME -- free other information, too */
+ drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
+ dev->agp = NULL;
+ }
+#endif
+}
+
+int r128_version(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_version_t version;
+ int len;
+
+ copy_from_user_ret(&version,
+ (drm_version_t *)arg,
+ sizeof(version),
+ -EFAULT);
+
+#define DRM_COPY(name,value) \
+ len = strlen(value); \
+ if (len > name##_len) len = name##_len; \
+ name##_len = strlen(value); \
+ if (len && name) { \
+ copy_to_user_ret(name, value, len, -EFAULT); \
+ }
+
+ version.version_major = R128_MAJOR;
+ version.version_minor = R128_MINOR;
+ version.version_patchlevel = R128_PATCHLEVEL;
+
+ DRM_COPY(version.name, R128_NAME);
+ DRM_COPY(version.date, R128_DATE);
+ DRM_COPY(version.desc, R128_DESC);
+
+ copy_to_user_ret((drm_version_t *)arg,
+ &version,
+ sizeof(version),
+ -EFAULT);
+ return 0;
+}
+
+int r128_open(struct inode *inode, struct file *filp)
+{
+ drm_device_t *dev = &r128_device;
+ int retcode = 0;
+
+ DRM_DEBUG("open_count = %d\n", dev->open_count);
+ if (!(retcode = drm_open_helper(inode, filp, dev))) {
+ MOD_INC_USE_COUNT;
+ atomic_inc(&dev->total_open);
+ spin_lock(&dev->count_lock);
+ if (!dev->open_count++) {
+ spin_unlock(&dev->count_lock);
+ return r128_setup(dev);
+ }
+ spin_unlock(&dev->count_lock);
+ }
+ return retcode;
+}
+
+int r128_release(struct inode *inode, struct file *filp)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ int retcode = 0;
+
+ DRM_DEBUG("open_count = %d\n", dev->open_count);
+ if (!(retcode = drm_release(inode, filp))) {
+ MOD_DEC_USE_COUNT;
+ atomic_inc(&dev->total_close);
+ spin_lock(&dev->count_lock);
+ if (!--dev->open_count) {
+ if (atomic_read(&dev->ioctl_count) || dev->blocked) {
+ DRM_ERROR("Device busy: %d %d\n",
+ atomic_read(&dev->ioctl_count),
+ dev->blocked);
+ spin_unlock(&dev->count_lock);
+ return -EBUSY;
+ }
+ spin_unlock(&dev->count_lock);
+ return r128_takedown(dev);
+ }
+ spin_unlock(&dev->count_lock);
+ }
+ return retcode;
+}
+
+/* r128_ioctl is called whenever a process performs an ioctl on /dev/drm. */
+
+int r128_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ int nr = DRM_IOCTL_NR(cmd);
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ int retcode = 0;
+ drm_ioctl_desc_t *ioctl;
+ drm_ioctl_t *func;
+
+ atomic_inc(&dev->ioctl_count);
+ atomic_inc(&dev->total_ioctl);
+ ++priv->ioctl_count;
+
+ DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
+ current->pid, cmd, nr, dev->device, priv->authenticated);
+
+ if (nr >= R128_IOCTL_COUNT) {
+ retcode = -EINVAL;
+ } else {
+ ioctl = &r128_ioctls[nr];
+ func = ioctl->func;
+
+ if (!func) {
+ DRM_DEBUG("no function\n");
+ retcode = -EINVAL;
+ } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
+ || (ioctl->auth_needed && !priv->authenticated)) {
+ retcode = -EACCES;
+ } else {
+ retcode = (func)(inode, filp, cmd, arg);
+ }
+ }
+
+ atomic_dec(&dev->ioctl_count);
+ return retcode;
+}
+
+int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ DECLARE_WAITQUEUE(entry, current);
+ int ret = 0;
+ drm_lock_t lock;
+#if DRM_DMA_HISTOGRAM
+ cycles_t start;
+
+ dev->lck_start = start = get_cycles();
+#endif
+
+ copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+
+ if (lock.context == DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("Process %d using kernel context %d\n",
+ current->pid, lock.context);
+ return -EINVAL;
+ }
+
+ DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
+ lock.context, current->pid, dev->lock.hw_lock->lock,
+ lock.flags);
+
+#if 0
+ /* dev->queue_count == 0 right now for
+ r128. FIXME? */
+ if (lock.context < 0 || lock.context >= dev->queue_count)
+ return -EINVAL;
+#endif
+
+ if (!ret) {
+#if 0
+ if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
+ != lock.context) {
+ long j = jiffies - dev->lock.lock_time;
+
+ if (lock.context == r128_res_ctx.handle &&
+ j >= 0 && j < DRM_LOCK_SLICE) {
+ /* Can't take lock if we just had it and
+ there is contention. */
+ DRM_DEBUG("%d (pid %d) delayed j=%d dev=%d jiffies=%d\n",
+ lock.context, current->pid, j,
+ dev->lock.lock_time, jiffies);
+ current->state = TASK_INTERRUPTIBLE;
+ current->policy |= SCHED_YIELD;
+ schedule_timeout(DRM_LOCK_SLICE-j);
+ DRM_DEBUG("jiffies=%d\n", jiffies);
+ }
+ }
+#endif
+ add_wait_queue(&dev->lock.lock_queue, &entry);
+ for (;;) {
+ if (!dev->lock.hw_lock) {
+ /* Device has been unregistered */
+ ret = -EINTR;
+ break;
+ }
+ if (drm_lock_take(&dev->lock.hw_lock->lock,
+ lock.context)) {
+ dev->lock.pid = current->pid;
+ dev->lock.lock_time = jiffies;
+ atomic_inc(&dev->total_locks);
+ break; /* Got lock */
+ }
+
+ /* Contention */
+ atomic_inc(&dev->total_sleeps);
+ current->state = TASK_INTERRUPTIBLE;
+#if 1
+ current->policy |= SCHED_YIELD;
+#endif
+ schedule();
+ if (signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ break;
+ }
+ }
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&dev->lock.lock_queue, &entry);
+ }
+
+#if 0
+ if (!ret && dev->last_context != lock.context &&
+ lock.context != r128_res_ctx.handle &&
+ dev->last_context != r128_res_ctx.handle) {
+ add_wait_queue(&dev->context_wait, &entry);
+ current->state = TASK_INTERRUPTIBLE;
+ /* PRE: dev->last_context != lock.context */
+ r128_context_switch(dev, dev->last_context, lock.context);
+ /* POST: we will wait for the context
+ switch and will dispatch on a later call
+ when dev->last_context == lock.context
+ NOTE WE HOLD THE LOCK THROUGHOUT THIS
+ TIME! */
+ current->policy |= SCHED_YIELD;
+ schedule();
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&dev->context_wait, &entry);
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ } else if (dev->last_context != lock.context) {
+ DRM_ERROR("Context mismatch: %d %d\n",
+ dev->last_context, lock.context);
+ }
+ }
+#endif
+
+ if (!ret) {
+ if (lock.flags & _DRM_LOCK_READY) {
+ /* Wait for space in DMA/FIFO */
+ }
+ if (lock.flags & _DRM_LOCK_QUIESCENT) {
+ /* Make hardware quiescent */
+#if 0
+ r128_quiescent(dev);
+#endif
+ }
+ }
+
+#if 0
+ DRM_ERROR("pid = %5d, old counter = %5ld\n",
+ current->pid, current->counter);
+#endif
+ if (lock.context != r128_res_ctx.handle) {
+ current->counter = 5;
+ current->priority = DEF_PRIORITY/4;
+ }
+#if 0
+ while (current->counter > 25)
+ current->counter >>= 1; /* decrease time slice */
+ DRM_ERROR("pid = %5d, new counter = %5ld\n",
+ current->pid, current->counter);
+#endif
+ DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
+
+#if DRM_DMA_HISTOGRAM
+ atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
+#endif
+
+ return ret;
+}
+
+
+int r128_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_lock_t lock;
+
+ copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+
+ if (lock.context == DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("Process %d using kernel context %d\n",
+ current->pid, lock.context);
+ return -EINVAL;
+ }
+
+ DRM_DEBUG("%d frees lock (%d holds)\n",
+ lock.context,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+ atomic_inc(&dev->total_unlocks);
+ if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
+ atomic_inc(&dev->total_contends);
+ drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
+ /* FIXME: Try to send data to card here */
+ if (!dev->context_flag) {
+ if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ DRM_ERROR("\n");
+ }
+ }
+
+#if 0
+ current->policy |= SCHED_YIELD;
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(1000);
+#endif
+
+ if (lock.context != r128_res_ctx.handle) {
+ current->counter = 5;
+ current->priority = DEF_PRIORITY;
+ }
+#if 0
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(10);
+#endif
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h
new file mode 100644
index 000000000..3b888c493
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h
@@ -0,0 +1,226 @@
+/* r128_drv.h -- Private header for r128 driver -*- linux-c -*-
+ * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com>
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $XFree86$
+ *
+ */
+
+#ifndef _R128_DRV_H_
+#define _R128_DRV_H_
+
+typedef struct drm_r128_private {
+ int is_pci;
+
+ int cce_mode;
+ int cce_fifo_size;
+ int cce_is_bm_mode;
+ int cce_secure;
+
+ drm_r128_sarea_t *sarea_priv;
+
+ __volatile__ u32 *ring_read_ptr;
+
+ u32 *ring_start;
+ u32 *ring_end;
+ int ring_size;
+ int ring_sizel2qw;
+ int ring_entries;
+
+ int submit_age;
+
+ int usec_timeout;
+
+ drm_map_t *sarea;
+ drm_map_t *fb;
+ drm_map_t *agp_ring;
+ drm_map_t *agp_read_ptr;
+ drm_map_t *agp_vertbufs;
+ drm_map_t *agp_indbufs;
+ drm_map_t *agp_textures;
+ drm_map_t *mmio;
+} drm_r128_private_t;
+
+typedef struct drm_r128_buf_priv {
+ u32 age;
+} drm_r128_buf_priv_t;
+
+ /* r128_drv.c */
+extern int r128_init(void);
+extern void r128_cleanup(void);
+extern int r128_version(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int r128_open(struct inode *inode, struct file *filp);
+extern int r128_release(struct inode *inode, struct file *filp);
+extern int r128_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int r128_lock(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int r128_unlock(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+
+ /* r128_dma.c */
+extern int r128_init_cce(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int r128_eng_reset(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int r128_eng_flush(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int r128_submit_pkt(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int r128_cce_idle(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int r128_vertex_buf(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+
+ /* r128_bufs.c */
+extern int r128_addbufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int r128_mapbufs(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+
+ /* r128_context.c */
+extern int r128_resctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int r128_addctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int r128_modctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int r128_getctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int r128_switchctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int r128_newctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int r128_rmctx(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+
+extern int r128_context_switch(drm_device_t *dev, int old, int new);
+extern int r128_context_switch_complete(drm_device_t *dev, int new);
+
+
+/* Register definitions, register access macros and drmAddMap constants
+ * for Rage 128 kernel driver.
+ */
+
+#define R128_PC_NGUI_CTLSTAT 0x0184
+# define R128_PC_FLUSH_ALL 0x00ff
+# define R128_PC_BUSY (1 << 31)
+
+#define R128_CLOCK_CNTL_INDEX 0x0008
+#define R128_CLOCK_CNTL_DATA 0x000c
+# define R128_PLL_WR_EN (1 << 7)
+
+#define R128_MCLK_CNTL 0x000f
+# define R128_FORCE_GCP (1 << 16)
+# define R128_FORCE_PIPE3D_CPP (1 << 17)
+
+#define R128_GEN_RESET_CNTL 0x00f0
+# define R128_SOFT_RESET_GUI (1 << 0)
+
+#define R128_PM4_BUFFER_CNTL 0x0704
+# define R128_PM4_NONPM4 (0 << 28)
+# define R128_PM4_192PIO (1 << 28)
+# define R128_PM4_192BM (2 << 28)
+# define R128_PM4_128PIO_64INDBM (3 << 28)
+# define R128_PM4_128BM_64INDBM (4 << 28)
+# define R128_PM4_64PIO_128INDBM (5 << 28)
+# define R128_PM4_64BM_128INDBM (6 << 28)
+# define R128_PM4_64PIO_64VCBM_64INDBM (7 << 28)
+# define R128_PM4_64BM_64VCBM_64INDBM (8 << 28)
+# define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28)
+
+
+#define R128_PM4_BUFFER_DL_RPTR 0x0710
+#define R128_PM4_BUFFER_DL_WPTR 0x0714
+# define R128_PM4_BUFFER_DL_DONE (1 << 31)
+
+#define R128_PM4_VC_FPU_SETUP 0x071c
+
+#define R128_PM4_STAT 0x07b8
+# define R128_PM4_FIFOCNT_MASK 0x0fff
+# define R128_PM4_BUSY (1 << 16)
+# define R128_PM4_GUI_ACTIVE (1 << 31)
+
+#define R128_PM4_BUFFER_ADDR 0x07f0
+#define R128_PM4_MICRO_CNTL 0x07fc
+# define R128_PM4_MICRO_FREERUN (1 << 30)
+
+#define R128_PM4_FIFO_DATA_EVEN 0x1000
+#define R128_PM4_FIFO_DATA_ODD 0x1004
+
+#define R128_GUI_SCRATCH_REG0 0x15e0
+#define R128_GUI_SCRATCH_REG1 0x15e4
+#define R128_GUI_SCRATCH_REG2 0x15e8
+#define R128_GUI_SCRATCH_REG3 0x15ec
+#define R128_GUI_SCRATCH_REG4 0x15f0
+#define R128_GUI_SCRATCH_REG5 0x15f4
+
+#define R128_GUI_STAT 0x1740
+# define R128_GUI_FIFOCNT_MASK 0x0fff
+# define R128_GUI_ACTIVE (1 << 31)
+
+
+/* CCE command packets */
+#define R128_CCE_PACKET0 0x00000000
+#define R128_CCE_PACKET1 0x40000000
+#define R128_CCE_PACKET2 0x80000000
+# define R128_CCE_PACKET_MASK 0xC0000000
+# define R128_CCE_PACKET_COUNT_MASK 0x3fff0000
+# define R128_CCE_PACKET0_REG_MASK 0x000007ff
+# define R128_CCE_PACKET1_REG0_MASK 0x000007ff
+# define R128_CCE_PACKET1_REG1_MASK 0x003ff800
+
+
+#define R128_MAX_USEC_TIMEOUT 100000 /* 100 ms */
+
+
+#define R128_BASE(reg) ((u32)(dev_priv->mmio->handle))
+#define R128_ADDR(reg) (R128_BASE(reg) + reg)
+
+#define R128_DEREF(reg) *(__volatile__ int *)R128_ADDR(reg)
+#define R128_READ(reg) R128_DEREF(reg)
+#define R128_WRITE(reg,val) do { R128_DEREF(reg) = val; } while (0)
+
+#define R128_DEREF8(reg) *(__volatile__ char *)R128_ADDR(reg)
+#define R128_READ8(reg) R128_DEREF8(reg)
+#define R128_WRITE8(reg,val) do { R128_DEREF8(reg) = val; } while (0)
+
+#define R128_WRITE_PLL(addr,val) \
+do { \
+ R128_WRITE8(R128_CLOCK_CNTL_INDEX, ((addr) & 0x1f) | R128_PLL_WR_EN); \
+ R128_WRITE(R128_CLOCK_CNTL_DATA, (val)); \
+} while (0)
+
+extern int R128_READ_PLL(drm_device_t *dev, int addr);
+
+#define R128CCE0(p,r,n) ((p) | ((n) << 16) | ((r) >> 2))
+#define R128CCE1(p,r1,r2) ((p) | (((r2) >> 2) << 11) | ((r1) >> 2))
+#define R128CCE2(p) ((p))
+#define R128CCE3(p,n) ((p) | ((n) << 16))
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c
index 534723a50..0b2b00e0a 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c
@@ -247,6 +247,18 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
/* Check for valid size. */
if (map->size != vma->vm_end - vma->vm_start) return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
+ vma->vm_flags &= VM_MAYWRITE;
+#if defined(__i386__)
+ pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
+#else
+ /* Ye gads this is ugly. With more thought
+ we could move this up higher and use
+ `protection_map' instead. */
+ vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect(
+ __pte(pgprot_val(vma->vm_page_prot)))));
+#endif
+ }
switch (map->type) {
case _DRM_FRAME_BUFFER:
@@ -266,6 +278,10 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
return -EAGAIN;
+ DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx,"
+ " offset = 0x%lx\n",
+ map->type,
+ vma->vm_start, vma->vm_end, VM_OFFSET(vma));
vma->vm_ops = &drm_vm_ops;
break;
case _DRM_SHM:
@@ -278,19 +294,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
return -EINVAL; /* This should never happen. */
}
vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
- if (map->flags & _DRM_READ_ONLY) {
-#if defined(__i386__)
- pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
-#else
- /* Ye gads this is ugly. With more thought
- we could move this up higher and use
- `protection_map' instead. */
- vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect(
- __pte(pgprot_val(vma->vm_page_prot)))));
-#endif
- }
-
#if LINUX_VERSION_CODE < 0x020203 /* KERNEL_VERSION(2,2,3) */
/* In Linux 2.2.3 and above, this is
handled in do_mmap() in mm/mmap.c. */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c
new file mode 100644
index 000000000..b2489eeed
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c
@@ -0,0 +1,87 @@
+#ifdef XFree86Server
+# include "xf86.h"
+# include "xf86_OSproc.h"
+# include "xf86_ansic.h"
+# include "xf86Priv.h"
+# define _DRM_MALLOC xalloc
+# define _DRM_FREE xfree
+# ifndef XFree86LOADER
+# include <sys/stat.h>
+# include <sys/mman.h>
+# endif
+#else
+# include <stdio.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <ctype.h>
+# include <fcntl.h>
+# include <errno.h>
+# include <signal.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/ioctl.h>
+# include <sys/mman.h>
+# include <sys/time.h>
+# ifdef DRM_USE_MALLOC
+# define _DRM_MALLOC malloc
+# define _DRM_FREE free
+extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *);
+extern int xf86RemoveSIGIOHandler(int fd);
+# else
+# include <Xlibint.h>
+# define _DRM_MALLOC Xmalloc
+# define _DRM_FREE Xfree
+# endif
+#endif
+
+/* Not all systems have MAP_FAILED defined */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#include <sys/sysmacros.h> /* for makedev() */
+#include "xf86drm.h"
+#include "xf86drmI810.h"
+#include "drm.h"
+
+Bool drmI810CleanupDma(int driSubFD)
+{
+ drm_i810_init_t init;
+
+ memset(&init, 0, sizeof(drm_i810_init_t));
+ init.func = I810_CLEANUP_DMA;
+
+ if(ioctl(driSubFD, DRM_IOCTL_I810_INIT, &init)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool drmI810InitDma(int driSubFD, drmI810Init *info)
+{
+ drm_i810_init_t init;
+
+ memset(&init, 0, sizeof(drm_i810_init_t));
+
+ init.func = I810_INIT_DMA;
+ init.ring_map_idx = info->ring_map_idx;
+ init.buffer_map_idx = info->buffer_map_idx;
+ init.ring_start = info->start;
+ init.ring_end = info->end;
+ init.ring_size = info->size;
+ init.sarea_priv_offset = info->sarea_off;
+ init.front_offset = info->front_offset;
+ init.back_offset = info->back_offset;
+ init.depth_offset = info->depth_offset;
+ init.w = info->w;
+ init.h = info->h;
+ init.pitch = info->pitch;
+ init.pitch_bits = info->pitch_bits;
+
+ if(ioctl(driSubFD, DRM_IOCTL_I810_INIT, &init)) {
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c
new file mode 100644
index 000000000..99f267f3d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c
@@ -0,0 +1,199 @@
+/* xf86drmR128.c -- User-level interface to Rage 128 DRM device
+ * Created: Sun Apr 9 18:13:54 2000 by kevin@precisioninsight.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $XFree86$
+ *
+ */
+
+#ifdef XFree86Server
+# include "xf86.h"
+# include "xf86_OSproc.h"
+# include "xf86_ansic.h"
+# include "xf86Priv.h"
+# define _DRM_MALLOC xalloc
+# define _DRM_FREE xfree
+# ifndef XFree86LOADER
+# include <sys/stat.h>
+# include <sys/mman.h>
+# endif
+#else
+# include <stdio.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <ctype.h>
+# include <fcntl.h>
+# include <errno.h>
+# include <signal.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/ioctl.h>
+# include <sys/mman.h>
+# include <sys/time.h>
+# ifdef DRM_USE_MALLOC
+# define _DRM_MALLOC malloc
+# define _DRM_FREE free
+extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *);
+extern int xf86RemoveSIGIOHandler(int fd);
+# else
+# include <Xlibint.h>
+# define _DRM_MALLOC Xmalloc
+# define _DRM_FREE Xfree
+# endif
+#endif
+
+/* Not all systems have MAP_FAILED defined */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#include <sys/sysmacros.h> /* for makedev() */
+#include "xf86drm.h"
+#include "xf86drmR128.h"
+#include "drm.h"
+
+int drmR128InitCCE(int fd, drmR128Init *info)
+{
+ drm_r128_init_t init;
+
+ memset(&init, 0, sizeof(drm_r128_init_t));
+
+ init.func = R128_INIT_CCE;
+ init.sarea_priv_offset = info->sarea_priv_offset;
+ init.is_pci = info->is_pci;
+ init.cce_mode = info->cce_mode;
+ init.cce_fifo_size = info->cce_fifo_size;
+ init.cce_secure = info->cce_secure;
+ init.ring_size = info->ring_size;
+ init.usec_timeout = info->usec_timeout;
+
+ init.fb_offset = info->fb_offset;
+ init.agp_ring_offset = info->agp_ring_offset;
+ init.agp_read_ptr_offset = info->agp_read_ptr_offset;
+ init.agp_vertbufs_offset = info->agp_vertbufs_offset;
+ init.agp_indbufs_offset = info->agp_indbufs_offset;
+ init.agp_textures_offset = info->agp_textures_offset;
+ init.mmio_offset = info->mmio_offset;
+
+ if (ioctl(fd, DRM_IOCTL_R128_INIT, &init)) return -errno;
+
+ return 0;
+}
+
+int drmR128CleanupCCE(int fd)
+{
+ drm_r128_init_t init;
+
+ memset(&init, 0, sizeof(drm_r128_init_t));
+
+ init.func = R128_CLEANUP_CCE;
+
+ if (ioctl(fd, DRM_IOCTL_R128_INIT, &init)) return -errno;
+
+ return 0;
+}
+
+int drmR128EngineReset(int fd)
+{
+ if (ioctl(fd, DRM_IOCTL_R128_RESET, NULL)) return -errno;
+
+ return 0;
+}
+
+int drmR128EngineFlush(int fd)
+{
+ if (ioctl(fd, DRM_IOCTL_R128_FLUSH, NULL)) return -errno;
+
+ return 0;
+}
+
+int drmR128CCEWaitForIdle(int fd)
+{
+ if (ioctl(fd, DRM_IOCTL_R128_CCEIDL, NULL)) return -errno;
+
+ return 0;
+}
+
+int drmR128SubmitPackets(int fd, CARD32 *buffer, int *count, int flags)
+{
+ drm_r128_packet_t packet;
+ int ret;
+
+ memset(&packet, 0, sizeof(drm_r128_packet_t));
+
+ packet.count = *count;
+ packet.flags = flags;
+
+ while (packet.count > 0) {
+ packet.buffer = buffer + (*count - packet.count);
+ ret = ioctl(fd, DRM_IOCTL_R128_PACKET, &packet);
+ if (ret < 0 && ret != -EAGAIN) {
+ *count = packet.count;
+ return -errno;
+ }
+ }
+
+ *count = 0;
+ return 0;
+}
+
+int drmR128GetVertexBuffers(int fd, int count, int *indices, int *sizes)
+{
+ drm_r128_vertex_t v;
+
+ v.send_count = 0;
+ v.send_indices = NULL;
+ v.send_sizes = NULL;
+ v.prim = DRM_R128_PRIM_NONE;
+ v.request_count = count;
+ v.request_indices = indices;
+ v.request_sizes = sizes;
+ v.granted_count = 0;
+
+ if (ioctl(fd, DRM_IOCTL_R128_VERTEX, &v)) return -errno;
+
+ return v.granted_count;
+}
+
+int drmR128FlushVertexBuffers(int fd, int count, int *indices,
+ int *sizes, drmR128PrimType prim)
+{
+ drm_r128_vertex_t v;
+
+ v.send_count = count;
+ v.send_indices = indices;
+ v.send_sizes = sizes;
+ v.prim = prim;
+ v.request_count = 0;
+ v.request_indices = NULL;
+ v.request_sizes = NULL;
+ v.granted_count = 0;
+
+ if (ioctl(fd, DRM_IOCTL_R128_VERTEX, &v) < 0) return -errno;
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
index 15491aeeb..c8c5581da 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
@@ -72,9 +72,10 @@ typedef struct drm_clip_rect {
unsigned short y2;
} drm_clip_rect_t;
-/* Seperate include files for the i810/mga specific structures */
+/* Seperate include files for the i810/mga/r128 specific structures */
#include "mga_drm.h"
#include "i810_drm.h"
+#include "r128_drm.h"
typedef struct drm_version {
int version_major; /* Major version */
@@ -297,7 +298,7 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t)
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t)
-#define DRM_IOCTL_GET_MAGIC DRM_IOW( 0x02, drm_auth_t)
+#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t)
#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t)
@@ -328,11 +329,11 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
-#define DRM_IOCTL_AGP_ENABLE DRM_IOR( 0x32, drm_agp_mode_t)
-#define DRM_IOCTL_AGP_INFO DRM_IOW( 0x33, drm_agp_info_t)
+#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t)
+#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t)
#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t)
-#define DRM_IOCTL_AGP_BIND DRM_IOWR(0x36, drm_agp_binding_t)
+#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
/* Mga specific ioctls */
@@ -342,12 +343,23 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t)
#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t)
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t )
+#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t)
/* I810 specific ioctls */
#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t)
#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t)
-#define DRM_IOCTL_I810_DMA DRM_IOW( 0x42, drm_i810_general_t)
+#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t)
#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43)
#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44)
+#define DRM_IOCTL_I810_GETBUF DRM_IOW( 0x45, drm_i810_dma_t)
+#define DRM_IOCTL_I810_SWAP DRM_IO ( 0x46)
+
+/* Rage 128 specific ioctls */
+#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
+#define DRM_IOCTL_R128_RESET DRM_IO( 0x41)
+#define DRM_IOCTL_R128_FLUSH DRM_IO( 0x42)
+#define DRM_IOCTL_R128_CCEIDL DRM_IO( 0x43)
+#define DRM_IOCTL_R128_PACKET DRM_IOW( 0x44, drm_r128_packet_t)
+#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x45, drm_r128_vertex_t)
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
index 61287e3e2..372ba595e 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
@@ -1,8 +1,7 @@
/* xf86drm.h -- OS-independent header for DRM user-level library interface
* Created: Tue Jan 5 08:17:23 1999 by faith@precisioninsight.com
- * Revised: Sun Feb 13 23:46:21 2000 by kevin@precisioninsight.com
*
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -24,6 +23,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
+ * Author: Rickard E. (Rik) Faith <faith@precisioninsight.com>
+ *
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h,v 1.7 2000/02/23 04:47:21 martin Exp $
*
*/
@@ -65,7 +66,8 @@ typedef struct _drmVersion {
typedef enum {
DRM_FRAME_BUFFER = 0, /* WC, no caching, no core dump */
DRM_REGISTERS = 1, /* no caching, no core dump */
- DRM_SHM = 2 /* shared, cached */
+ DRM_SHM = 2, /* shared, cached */
+ DRM_AGP = 3 /* AGP/GART */
} drmMapType;
typedef enum {
@@ -95,6 +97,11 @@ typedef enum { /* These values *MUST* match drm.h */
} drmDMAFlags;
typedef enum {
+ DRM_PAGE_ALIGN = 0x01,
+ DRM_AGP_BUFFER = 0x02
+} drmBufDescFlags;
+
+typedef enum {
DRM_LOCK_READY = 0x01, /* Wait until hardware is ready for DMA */
DRM_LOCK_QUIESCENT = 0x02, /* Wait until hardware quiescent */
DRM_LOCK_FLUSH = 0x04, /* Flush this context's DMA queue first */
@@ -196,7 +203,7 @@ typedef struct { unsigned int a[100]; } __drm_dummy_lock_t;
#endif
#ifndef DRM_CAS
-#define DRM_CAS(lock,old,new,ret) /* FAST LOCK FAILS */
+#define DRM_CAS(lock,old,new,ret) do { ret=1; } while (0) /* FAST LOCK FAILS */
#endif
#define DRM_LIGHT_LOCK(fd,lock,context) \
@@ -291,7 +298,9 @@ extern int drmAddMap(int fd,
drmMapType type,
drmMapFlags flags,
drmHandlePtr handle);
-extern int drmAddBufs(int fd, int count, int size, int flags);
+extern int drmAddBufs(int fd, int count, int size,
+ drmBufDescFlags flags,
+ int agp_offset);
extern int drmMarkBufs(int fd, double low, double high);
extern int drmCreateContext(int fd, drmContextPtr handle);
extern int drmSetContextFlags(int fd, drmContext context,
@@ -332,6 +341,29 @@ extern int drmGetLock(int fd,
extern int drmUnlock(int fd, drmContext context);
extern int drmFinish(int fd, int context, drmLockFlags flags);
+/* AGP/GART support: X server (root) only */
+extern int drmAgpAcquire(int fd);
+extern int drmAgpRelease(int fd);
+extern int drmAgpEnable(int fd, unsigned long mode);
+extern int drmAgpAlloc(int fd, unsigned long size,
+ unsigned long type, unsigned long *address,
+ unsigned long *handle);
+extern int drmAgpFree(int fd, unsigned long handle);
+extern int drmAgpBind(int fd, unsigned long handle,
+ unsigned long offset);
+extern int drmAgpUnbind(int fd, unsigned long handle);
+
+/* AGP/GART info: authenticated client and/or X */
+extern int drmAgpVersionMajor(int fd);
+extern int drmAgpVersionMinor(int fd);
+extern unsigned long drmAgpGetMode(int fd);
+extern unsigned long drmAgpBase(int fd); /* Physical location */
+extern unsigned long drmAgpSize(int fd); /* Bytes */
+extern unsigned long drmAgpMemoryUsed(int fd);
+extern unsigned long drmAgpMemoryAvail(int fd);
+extern unsigned int drmAgpVendorId(int fd);
+extern unsigned int drmAgpDeviceId(int fd);
+
/* Support routines */
extern int drmError(int err, const char *label);
extern void *drmMalloc(int size);
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h
new file mode 100644
index 000000000..6c11b7a10
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h
@@ -0,0 +1,46 @@
+
+/* WARNING: If you change any of these defines, make sure to change
+ * the kernel include file as well (i810_drm.h)
+ */
+
+#ifndef _XF86DRI_I810_H_
+#define _XF86DRI_I810_H_
+
+#ifndef _I810_DEFINES_
+#define _I810_DEFINES_
+#define I810_USE_BATCH 1
+
+#define I810_DMA_BUF_ORDER 12
+#define I810_DMA_BUF_SZ (1<<I810_DMA_BUF_ORDER)
+#define I810_DMA_BUF_NR 256
+
+#define I810_NR_SAREA_CLIPRECTS 8
+
+/* Each region is a minimum of 64k, and there are at most 64 of them.
+ */
+#define I810_NR_TEX_REGIONS 64
+#define I810_LOG_MIN_TEX_REGION_SIZE 16
+#endif
+
+typedef struct _drmI810Init {
+ unsigned int start;
+ unsigned int end;
+ unsigned int size;
+ int ring_map_idx;
+ int buffer_map_idx;
+ int sarea_off;
+
+ unsigned int front_offset;
+ unsigned int back_offset;
+ unsigned int depth_offset;
+ unsigned int w;
+ unsigned int h;
+ unsigned int pitch;
+ unsigned int pitch_bits;
+} drmI810Init;
+
+
+Bool drmI810CleanupDma(int driSubFD);
+Bool drmI810InitDma(int driSubFD, drmI810Init *info );
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h
new file mode 100644
index 000000000..3b0e4a6fc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmMga.h
@@ -0,0 +1,147 @@
+
+/* WARNING: If you change any of these defines, make sure to change
+ * the kernel include file as well (mga_drm.h)
+ */
+
+#ifndef _XF86DRI_MGA_H_
+#define _XF86DRI_MGA_H_
+#ifndef _MGA_DEFINES_
+#define _MGA_DEFINES_
+#define MGA_F 0x1 /* fog */
+#define MGA_A 0x2 /* alpha */
+#define MGA_S 0x4 /* specular */
+#define MGA_T2 0x8 /* multitexture */
+
+#define MGA_WARP_TGZ 0
+#define MGA_WARP_TGZF (MGA_F)
+#define MGA_WARP_TGZA (MGA_A)
+#define MGA_WARP_TGZAF (MGA_F|MGA_A)
+#define MGA_WARP_TGZS (MGA_S)
+#define MGA_WARP_TGZSF (MGA_S|MGA_F)
+#define MGA_WARP_TGZSA (MGA_S|MGA_A)
+#define MGA_WARP_TGZSAF (MGA_S|MGA_F|MGA_A)
+#define MGA_WARP_T2GZ (MGA_T2)
+#define MGA_WARP_T2GZF (MGA_T2|MGA_F)
+#define MGA_WARP_T2GZA (MGA_T2|MGA_A)
+#define MGA_WARP_T2GZAF (MGA_T2|MGA_A|MGA_F)
+#define MGA_WARP_T2GZS (MGA_T2|MGA_S)
+#define MGA_WARP_T2GZSF (MGA_T2|MGA_S|MGA_F)
+#define MGA_WARP_T2GZSA (MGA_T2|MGA_S|MGA_A)
+#define MGA_WARP_T2GZSAF (MGA_T2|MGA_S|MGA_F|MGA_A)
+
+#define MGA_MAX_G400_PIPES 16
+#define MGA_MAX_G200_PIPES 8 /* no multitex */
+
+#define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES
+
+#define MGA_CARD_TYPE_G200 1
+#define MGA_CARD_TYPE_G400 2
+#define MGA_FRONT 0x1
+#define MGA_BACK 0x2
+#define MGA_DEPTH 0x4
+
+/* 3d state excluding texture units:
+ */
+#define MGA_CTXREG_DSTORG 0 /* validated */
+#define MGA_CTXREG_MACCESS 1
+#define MGA_CTXREG_PLNWT 2
+#define MGA_CTXREG_DWGCTL 3
+#define MGA_CTXREG_ALPHACTRL 4
+#define MGA_CTXREG_FOGCOLOR 5
+#define MGA_CTXREG_WFLAG 6
+#define MGA_CTXREG_TDUAL0 7
+#define MGA_CTXREG_TDUAL1 8
+#define MGA_CTXREG_FCOL 9
+#define MGA_CTX_SETUP_SIZE 10
+
+/* 2d state
+ */
+#define MGA_2DREG_PITCH 0
+#define MGA_2D_SETUP_SIZE 1
+
+/* Each texture unit has a state:
+ */
+#define MGA_TEXREG_CTL 0
+#define MGA_TEXREG_CTL2 1
+#define MGA_TEXREG_FILTER 2
+#define MGA_TEXREG_BORDERCOL 3
+#define MGA_TEXREG_ORG 4 /* validated */
+#define MGA_TEXREG_ORG1 5
+#define MGA_TEXREG_ORG2 6
+#define MGA_TEXREG_ORG3 7
+#define MGA_TEXREG_ORG4 8
+#define MGA_TEXREG_WIDTH 9
+#define MGA_TEXREG_HEIGHT 10
+#define MGA_TEX_SETUP_SIZE 11
+
+/* What needs to be changed for the current vertex dma buffer?
+ */
+#define MGA_UPLOAD_CTX 0x1
+#define MGA_UPLOAD_TEX0 0x2
+#define MGA_UPLOAD_TEX1 0x4
+#define MGA_UPLOAD_PIPE 0x8
+#define MGA_UPLOAD_TEX0IMAGE 0x10
+#define MGA_UPLOAD_TEX1IMAGE 0x20
+#define MGA_UPLOAD_2D 0x40
+#define MGA_WAIT_AGE 0x80 /* handled client-side */
+#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */
+#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock
+ quiescent */
+
+/* 32 buffers of 64k each, total 1 meg.
+ */
+#define MGA_DMA_BUF_ORDER 16
+#define MGA_DMA_BUF_SZ (1<<MGA_DMA_BUF_ORDER)
+#define MGA_DMA_BUF_NR 31
+
+/* Keep these small for testing.
+ */
+#define MGA_NR_SAREA_CLIPRECTS 8
+
+/* 2 heaps (1 for card, 1 for agp), each divided into upto 128
+ * regions, subject to a minimum region size of (1<<16) == 64k.
+ *
+ * Clients may subdivide regions internally, but when sharing between
+ * clients, the region size is the minimum granularity.
+ */
+
+#define MGA_CARD_HEAP 0
+#define MGA_AGP_HEAP 1
+#define MGA_NR_TEX_HEAPS 2
+#define MGA_NR_TEX_REGIONS 16
+#define MGA_LOG_MIN_TEX_REGION_SIZE 16
+#endif
+
+typedef struct _drmMgaWarpIndex {
+ int installed;
+ unsigned long phys_addr;
+ int size;
+} drmMgaWarpIndex;
+
+typedef struct _drmMgaInit {
+ int reserved_map_agpstart;
+ int reserved_map_idx;
+ int buffer_map_idx;
+ int sarea_priv_offset;
+ int primary_size;
+ int warp_ucode_size;
+ unsigned int frontOffset;
+ unsigned int backOffset;
+ unsigned int depthOffset;
+ unsigned int textureOffset;
+ unsigned int textureSize;
+ unsigned int agpTextureSize;
+ unsigned int agpTextureOffset;
+ unsigned int cpp;
+ unsigned int stride;
+ int sgram;
+ int chipset;
+ drmMgaWarpIndex WarpIndex[MGA_MAX_WARP_PIPES];
+ unsigned int mAccess;
+} drmMgaInit;
+
+
+Bool drmMgaCleanupDma(int driSubFD);
+Bool drmMgaLockUpdate(int driSubFD, drmLockFlags flags);
+Bool drmMgaInitDma(int driSubFD, drmMgaInit *info);
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h
new file mode 100644
index 000000000..46898a53c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h
@@ -0,0 +1,80 @@
+/* xf86drm.h -- OS-independent header for DRM user-level library interface
+ * Created: Sun Apr 9 18:16:28 2000 by kevin@precisioninsight.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $XFree86$
+ *
+ */
+
+#ifndef _XF86DRI_R128_H_
+#define _XF86DRI_R128_H_
+
+/* WARNING: If you change any of these defines, make sure to change
+ * the kernel include file as well (r128_drm.h)
+ */
+
+typedef struct _drmR128Init {
+ int sarea_priv_offset;
+ int is_pci;
+ int cce_mode;
+ int cce_fifo_size;
+ int cce_secure;
+ int ring_size;
+ int usec_timeout;
+
+ int fb_offset;
+ int agp_ring_offset;
+ int agp_read_ptr_offset;
+ int agp_vertbufs_offset;
+ int agp_indbufs_offset;
+ int agp_textures_offset;
+ int mmio_offset;
+} drmR128Init;
+
+typedef enum {
+ DRM_R128_PRIM_NONE = 0x0001,
+ DRM_R128_PRIM_POINT = 0x0002,
+ DRM_R128_PRIM_LINE = 0x0004,
+ DRM_R128_PRIM_POLY_LINE = 0x0008,
+ DRM_R128_PRIM_TRI_LIST = 0x0010,
+ DRM_R128_PRIM_TRI_FAN = 0x0020,
+ DRM_R128_PRIM_TRI_STRIP = 0x0040,
+ DRM_R128_PRIM_TRI_TYPE2 = 0x0080
+} drmR128PrimType;
+
+
+extern int drmR128InitCCE(int fd, drmR128Init *info);
+extern int drmR128CleanupCCE(int fd);
+extern int drmR128EngineReset(int fd);
+extern int drmR128EngineFlush(int fd);
+extern int drmR128CCEWaitForIdle(int fd);
+extern int drmR128SubmitPackets(int fd, CARD32 *buffer, int *count, int flags);
+extern int drmR128GetVertexBuffers(int fd, int count, int *indices,
+ int *sizes);
+extern int drmR128FlushVertexBuffers(int fd, int count, int *indices,
+ int *sizes, drmR128PrimType prim);
+
+#endif