diff options
author | Eric Anholt <anholt@freebsd.org> | 2003-12-29 06:24:01 +0000 |
---|---|---|
committer | Eric Anholt <anholt@freebsd.org> | 2003-12-29 06:24:01 +0000 |
commit | df03e80ae9162ec87f503322ccbcf2846ad38bef (patch) | |
tree | 687daa27cf3702e04e9f2c016c4c0680ddda8b2e /hw | |
parent | 9bea538745f1a0c14faaac0e61dee5cf86f98dc6 (diff) |
Merge dri-0-1-branch to trunk. Notable changes:
- Add libdrm and libdri. Portions of the DRI extension are stubbed out.
- Use the DRM in the ATI driver when available. This provides a minor
performance improvement in x11perf, and opens the possibility of using
the 3d hardware for acceleration in the future.
- Implement solid fill acceleration for Composite in KAA.
- Implement Blend hook for Composite and use it on r128.
- Fix a bug of mine that resulted in overuse of offscreen memory.
- Fix many miscellaneous bugs in ATI driver and add PCI IDs.
Diffstat (limited to 'hw')
-rw-r--r-- | hw/kdrive/ati/Makefile.am | 23 | ||||
-rw-r--r-- | hw/kdrive/ati/ati.c | 282 | ||||
-rw-r--r-- | hw/kdrive/ati/ati.h | 113 | ||||
-rw-r--r-- | hw/kdrive/ati/ati_draw.c | 486 | ||||
-rw-r--r-- | hw/kdrive/ati/ati_draw.h | 82 | ||||
-rw-r--r-- | hw/kdrive/ati/ati_drawtmp.h | 241 | ||||
-rw-r--r-- | hw/kdrive/ati/ati_dri.c | 929 | ||||
-rw-r--r-- | hw/kdrive/ati/ati_dri.h | 100 | ||||
-rw-r--r-- | hw/kdrive/ati/ati_dripriv.h | 58 | ||||
-rw-r--r-- | hw/kdrive/ati/ati_reg.h | 138 | ||||
-rw-r--r-- | hw/kdrive/ati/ati_sarea.h | 42 | ||||
-rw-r--r-- | hw/kdrive/ati/ati_stub.c | 23 | ||||
-rw-r--r-- | hw/kdrive/ati/r128_blendtmp.h | 125 | ||||
-rw-r--r-- | hw/kdrive/ati/r128_common.h | 171 | ||||
-rw-r--r-- | hw/kdrive/ati/r128_sarea.h | 186 | ||||
-rw-r--r-- | hw/kdrive/ati/radeon_common.h | 461 | ||||
-rw-r--r-- | hw/kdrive/ati/radeon_sarea.h | 222 | ||||
-rw-r--r-- | hw/kdrive/src/Makefile.am | 2 | ||||
-rw-r--r-- | hw/kdrive/src/kaa.c | 112 | ||||
-rw-r--r-- | hw/kdrive/src/kaa.h | 95 | ||||
-rw-r--r-- | hw/kdrive/src/kaapict.c | 418 | ||||
-rw-r--r-- | hw/kdrive/src/kdrive.h | 13 |
22 files changed, 3877 insertions, 445 deletions
diff --git a/hw/kdrive/ati/Makefile.am b/hw/kdrive/ati/Makefile.am index e694d018c..69c88f019 100644 --- a/hw/kdrive/ati/Makefile.am +++ b/hw/kdrive/ati/Makefile.am @@ -1,3 +1,17 @@ +if DRI +DRI_INCLUDES = -I$(top_srcdir)/dri \ + -I$(top_srcdir)/drm +DRI_LIBS = $(top_builddir)/dri/libdri.a \ + $(top_builddir)/drm/libdrm.a +DRI_SOURCES = ati_dri.c \ + ati_dri.h \ + ati_dripriv.h \ + r128_common.h \ + r128_sarea.h \ + radeon_common.h \ + radeon_sarea.h +endif + if KDRIVEFBDEV FBDEV_INCLUDES =-I$(top_srcdir)/hw/kdrive/fbdev FBDEV_LIBS = $(top_builddir)/hw/kdrive/fbdev/libfbdev.a @@ -8,9 +22,9 @@ VESA_INCLUDES = -I$(top_srcdir)/hw/kdrive/vesa VESA_LIBS = $(top_builddir)/hw/kdrive/vesa/libvesa.a endif - INCLUDES = \ @KDRIVE_INCS@ \ + $(DRI_INCLUDES) \ $(FBDEV_INCLUDES) \ $(VESA_INCLUDES) \ @XSERVER_CFLAGS@ @@ -25,15 +39,20 @@ noinst_LIBRARIES = libati.a libati_a_SOURCES = \ ati_draw.c \ + ati_draw.h \ + ati_drawtmp.h \ ati.c \ ati.h \ - ati_reg.h + ati_reg.h \ + r128_blendtmp.h \ + $(DRI_SOURCES) Xati_SOURCES = \ ati_stub.c Xati_LDADD = \ libati.a \ + $(DRI_LIBS) \ $(FBDEV_LIBS) \ $(VESA_LIBS) \ @KDRIVE_LIBS@ \ diff --git a/hw/kdrive/ati/ati.c b/hw/kdrive/ati/ati.c index 67137dff6..bdd3c4941 100644 --- a/hw/kdrive/ati/ati.c +++ b/hw/kdrive/ati/ati.c @@ -27,130 +27,140 @@ #include <config.h> #endif #include "ati.h" - -struct pci_id_list radeon_id_list[] = { - {0x1002, 0x4136, "ATI Radeon RS100"}, - {0x1002, 0x4137, "ATI Radeon RS200"}, - {0x1002, 0x4237, "ATI Radeon RS250"}, - {0x1002, 0x4144, "ATI Radeon R300 AD"}, - {0x1002, 0x4145, "ATI Radeon R300 AE"}, - {0x1002, 0x4146, "ATI Radeon R300 AF"}, - {0x1002, 0x4147, "ATI Radeon R300 AG"}, - {0x1002, 0x4148, "ATI Radeon R350 AH"}, - {0x1002, 0x4149, "ATI Radeon R350 AI"}, - {0x1002, 0x414a, "ATI Radeon R350 AJ"}, - {0x1002, 0x414b, "ATI Radeon R350 AK"}, - {0x1002, 0x4150, "ATI Radeon RV350 AP"}, - {0x1002, 0x4151, "ATI Radeon RV350 AQ"}, - {0x1002, 0x4152, "ATI Radeon RV350 AR"}, - {0x1002, 0x4153, "ATI Radeon RV350 AS"}, - {0x1002, 0x4154, "ATI Radeon RV350 AT"}, - {0x1002, 0x4156, "ATI Radeon RV350 AV"}, - {0x1002, 0x4242, "ATI Radeon R200 BB"}, - {0x1002, 0x4243, "ATI Radeon R200 BC"}, - {0x1002, 0x4336, "ATI Radeon RS100"}, - {0x1002, 0x4337, "ATI Radeon RS200"}, - {0x1002, 0x4437, "ATI Radeon RS250"}, - {0x1002, 0x4964, "ATI Radeon RV250 Id"}, - {0x1002, 0x4965, "ATI Radeon RV250 Ie"}, - {0x1002, 0x4966, "ATI Radeon RV250 If"}, - {0x1002, 0x4967, "ATI Radeon RV250 Ig"}, - {0x1002, 0x4c57, "ATI Radeon RV200 LW"}, - {0x1002, 0x4c58, "ATI Radeon RV200 LX"}, - {0x1002, 0x4c59, "ATI Radeon Mobility M6 LY"}, - {0x1002, 0x4c5a, "ATI Radeon Mobility LZ"}, - {0x1002, 0x4c64, "ATI Radeon RV250 Ld"}, - {0x1002, 0x4c65, "ATI Radeon RV250 Le"}, - {0x1002, 0x4c66, "ATI Radeon Mobility M9 RV250 Lf"}, - {0x1002, 0x4c67, "ATI Radeon RV250 Lg"}, - {0x1002, 0x4e44, "ATI Radeon R300 ND"}, - {0x1002, 0x4e45, "ATI Radeon R300 NE"}, - {0x1002, 0x4e46, "ATI Radeon R300 NF"}, - {0x1002, 0x4e47, "ATI Radeon R300 NG"}, - {0x1002, 0x4e48, "ATI Radeon R350 NH"}, - {0x1002, 0x4e49, "ATI Radeon R350 NI"}, - {0x1002, 0x4e4a, "ATI Radeon R350 NJ"}, - {0x1002, 0x4e4b, "ATI Radeon R350 NK"}, - {0x1002, 0x4e50, "ATI Radeon Mobility RV350 NP"}, - {0x1002, 0x4e51, "ATI Radeon Mobility RV350 NQ"}, - {0x1002, 0x4e52, "ATI Radeon Mobility RV350 NR"}, - {0x1002, 0x4e53, "ATI Radeon Mobility RV350 NS"}, - {0x1002, 0x4e54, "ATI Radeon Mobility RV350 NT"}, - {0x1002, 0x4e56, "ATI Radeon Mobility RV350 NV"}, - {0x1002, 0x5144, "ATI Radeon R100 QD"}, - {0x1002, 0x5145, "ATI Radeon R100 QE"}, - {0x1002, 0x5146, "ATI Radeon R100 QF"}, - {0x1002, 0x5147, "ATI Radeon R100 QG"}, - {0x1002, 0x5148, "ATI Radeon R200 QH"}, - {0x1002, 0x514c, "ATI Radeon R200 QL"}, - {0x1002, 0x514d, "ATI Radeon R200 QM"}, - {0x1002, 0x5157, "ATI Radeon RV200 QW"}, - {0x1002, 0x5158, "ATI Radeon RV200 QX"}, - {0x1002, 0x5159, "ATI Radeon RV100 QY"}, - {0x1002, 0x515a, "ATI Radeon RV100 QZ"}, - {0x1002, 0x5834, "ATI Radeon RS300"}, - {0x1002, 0x5835, "ATI Radeon Mobility RS300"}, - {0x1002, 0x5941, "ATI Radeon RV280 (9200)"}, - {0x1002, 0x5961, "ATI Radeon RV280 (9200 SE)"}, - {0x1002, 0x5964, "ATI Radeon RV280 (9200 SE)"}, - {0x1002, 0x5c60, "ATI Radeon RV280"}, - {0x1002, 0x5c61, "ATI Mobility Radeon RV280"}, - {0x1002, 0x5c62, "ATI Radeon RV280"}, - {0x1002, 0x5c63, "ATI Mobility Radeon RV280"}, - {0x1002, 0x5c64, "ATI Radeon RV280"}, - {0, 0, NULL} +#include "ati_reg.h" + +struct pci_id_entry ati_pci_ids[] = { + {0x1002, 0x4136, 0x1, "ATI Radeon RS100"}, + {0x1002, 0x4137, 0x3, "ATI Radeon RS200"}, + {0x1002, 0x4237, 0x3, "ATI Radeon RS250"}, + {0x1002, 0x4144, 0x5, "ATI Radeon R300 AD"}, + {0x1002, 0x4145, 0x5, "ATI Radeon R300 AE"}, + {0x1002, 0x4146, 0x5, "ATI Radeon R300 AF"}, + {0x1002, 0x4147, 0x5, "ATI Radeon R300 AG"}, + {0x1002, 0x4148, 0x5, "ATI Radeon R350 AH"}, + {0x1002, 0x4149, 0x5, "ATI Radeon R350 AI"}, + {0x1002, 0x414a, 0x5, "ATI Radeon R350 AJ"}, + {0x1002, 0x414b, 0x5, "ATI Radeon R350 AK"}, + {0x1002, 0x4150, 0x5, "ATI Radeon RV350 AP"}, + {0x1002, 0x4151, 0x5, "ATI Radeon RV350 AQ"}, + {0x1002, 0x4152, 0x5, "ATI Radeon RV350 AR"}, + {0x1002, 0x4153, 0x5, "ATI Radeon RV350 AS"}, + {0x1002, 0x4154, 0x5, "ATI Radeon RV350 AT"}, + {0x1002, 0x4156, 0x5, "ATI Radeon RV350 AV"}, + {0x1002, 0x4242, 0x3, "ATI Radeon R200 BB"}, + {0x1002, 0x4243, 0x3, "ATI Radeon R200 BC"}, + {0x1002, 0x4336, 0x1, "ATI Radeon RS100"}, + {0x1002, 0x4337, 0x3, "ATI Radeon RS200"}, + {0x1002, 0x4437, 0x3, "ATI Radeon RS250"}, + {0x1002, 0x4964, 0x3, "ATI Radeon RV250 Id"}, + {0x1002, 0x4965, 0x3, "ATI Radeon RV250 Ie"}, + {0x1002, 0x4966, 0x3, "ATI Radeon RV250 If"}, + {0x1002, 0x4967, 0x3, "ATI Radeon RV250 Ig"}, + {0x1002, 0x4c45, 0x0, "ATI Rage 128 LE"}, + {0x1002, 0x4c46, 0x0, "ATI Rage 128 LF"}, + {0x1002, 0x4c57, 0x3, "ATI Radeon RV200 LW"}, + {0x1002, 0x4c58, 0x3, "ATI Radeon RV200 LX"}, + {0x1002, 0x4c59, 0x3, "ATI Radeon Mobility M6 LY"}, + {0x1002, 0x4c5a, 0x3, "ATI Radeon Mobility LZ"}, + {0x1002, 0x4c64, 0x3, "ATI Radeon RV250 Ld"}, + {0x1002, 0x4c65, 0x3, "ATI Radeon RV250 Le"}, + {0x1002, 0x4c66, 0x3, "ATI Radeon Mobility M9 RV250 Lf"}, + {0x1002, 0x4c67, 0x3, "ATI Radeon RV250 Lg"}, + {0x1002, 0x4d46, 0x0, "ATI Rage 128 MF"}, + {0x1002, 0x4d46, 0x0, "ATI Rage 128 ML"}, + {0x1002, 0x4e44, 0x5, "ATI Radeon R300 ND"}, + {0x1002, 0x4e45, 0x5, "ATI Radeon R300 NE"}, + {0x1002, 0x4e46, 0x5, "ATI Radeon R300 NF"}, + {0x1002, 0x4e47, 0x5, "ATI Radeon R300 NG"}, + {0x1002, 0x4e48, 0x5, "ATI Radeon R350 NH"}, + {0x1002, 0x4e49, 0x5, "ATI Radeon R350 NI"}, + {0x1002, 0x4e4a, 0x5, "ATI Radeon R350 NJ"}, + {0x1002, 0x4e4b, 0x5, "ATI Radeon R350 NK"}, + {0x1002, 0x4e50, 0x5, "ATI Radeon Mobility RV350 NP"}, + {0x1002, 0x4e51, 0x5, "ATI Radeon Mobility RV350 NQ"}, + {0x1002, 0x4e52, 0x5, "ATI Radeon Mobility RV350 NR"}, + {0x1002, 0x4e53, 0x5, "ATI Radeon Mobility RV350 NS"}, + {0x1002, 0x4e54, 0x5, "ATI Radeon Mobility RV350 NT"}, + {0x1002, 0x4e56, 0x5, "ATI Radeon Mobility RV350 NV"}, + {0x1002, 0x5041, 0x0, "ATI Rage 128 PA"}, + {0x1002, 0x5042, 0x0, "ATI Rage 128 PB"}, + {0x1002, 0x5043, 0x0, "ATI Rage 128 PC"}, + {0x1002, 0x5044, 0x0, "ATI Rage 128 PD"}, + {0x1002, 0x5045, 0x0, "ATI Rage 128 PE"}, + {0x1002, 0x5046, 0x0, "ATI Rage 128 PF"}, + {0x1002, 0x5047, 0x0, "ATI Rage 128 PG"}, + {0x1002, 0x5048, 0x0, "ATI Rage 128 PH"}, + {0x1002, 0x5049, 0x0, "ATI Rage 128 PI"}, + {0x1002, 0x504a, 0x0, "ATI Rage 128 PJ"}, + {0x1002, 0x504b, 0x0, "ATI Rage 128 PK"}, + {0x1002, 0x504c, 0x0, "ATI Rage 128 PL"}, + {0x1002, 0x504d, 0x0, "ATI Rage 128 PM"}, + {0x1002, 0x504e, 0x0, "ATI Rage 128 PN"}, + {0x1002, 0x504f, 0x0, "ATI Rage 128 PO"}, + {0x1002, 0x5050, 0x0, "ATI Rage 128 PP"}, + {0x1002, 0x5051, 0x0, "ATI Rage 128 PQ"}, + {0x1002, 0x5052, 0x0, "ATI Rage 128 PR"}, + {0x1002, 0x5053, 0x0, "ATI Rage 128 PS"}, + {0x1002, 0x5054, 0x0, "ATI Rage 128 PT"}, + {0x1002, 0x5055, 0x0, "ATI Rage 128 PU"}, + {0x1002, 0x5056, 0x0, "ATI Rage 128 PV"}, + {0x1002, 0x5057, 0x0, "ATI Rage 128 PW"}, + {0x1002, 0x5058, 0x0, "ATI Rage 128 PX"}, + {0x1002, 0x5144, 0x1, "ATI Radeon R100 QD"}, + {0x1002, 0x5145, 0x1, "ATI Radeon R100 QE"}, + {0x1002, 0x5146, 0x1, "ATI Radeon R100 QF"}, + {0x1002, 0x5147, 0x1, "ATI Radeon R100 QG"}, + {0x1002, 0x5148, 0x1, "ATI Radeon R200 QH"}, + {0x1002, 0x514c, 0x1, "ATI Radeon R200 QL"}, + {0x1002, 0x514d, 0x1, "ATI Radeon R200 QM"}, + {0x1002, 0x5157, 0x1, "ATI Radeon RV200 QW"}, + {0x1002, 0x5158, 0x1, "ATI Radeon RV200 QX"}, + {0x1002, 0x5159, 0x1, "ATI Radeon RV100 QY"}, + {0x1002, 0x515a, 0x1, "ATI Radeon RV100 QZ"}, + {0x1002, 0x5245, 0x0, "ATI Rage 128 RE"}, + {0x1002, 0x5246, 0x0, "ATI Rage 128 RF"}, + {0x1002, 0x5247, 0x0, "ATI Rage 128 RG"}, + {0x1002, 0x524b, 0x0, "ATI Rage 128 RK"}, + {0x1002, 0x524c, 0x0, "ATI Rage 128 RL"}, + {0x1002, 0x5345, 0x0, "ATI Rage 128 SE"}, + {0x1002, 0x5346, 0x0, "ATI Rage 128 SF"}, + {0x1002, 0x5347, 0x0, "ATI Rage 128 SG"}, + {0x1002, 0x5348, 0x0, "ATI Rage 128 SH"}, + {0x1002, 0x534b, 0x0, "ATI Rage 128 SK"}, + {0x1002, 0x534c, 0x0, "ATI Rage 128 SL"}, + {0x1002, 0x534d, 0x0, "ATI Rage 128 SM"}, + {0x1002, 0x534e, 0x0, "ATI Rage 128 SN"}, + {0x1002, 0x5446, 0x0, "ATI Rage 128 TF"}, + {0x1002, 0x544c, 0x0, "ATI Rage 128 TL"}, + {0x1002, 0x5452, 0x0, "ATI Rage 128 TR"}, + {0x1002, 0x5453, 0x0, "ATI Rage 128 TS"}, + {0x1002, 0x5454, 0x0, "ATI Rage 128 TT"}, + {0x1002, 0x5455, 0x0, "ATI Rage 128 TU"}, + {0x1002, 0x5834, 0x5, "ATI Radeon RS300"}, + {0x1002, 0x5835, 0x5, "ATI Radeon RS300 Mobility"}, + {0x1002, 0x5941, 0x3, "ATI Radeon RV280 (9200)"}, + {0x1002, 0x5961, 0x3, "ATI Radeon RV280 (9200 SE)"}, + {0x1002, 0x5964, 0x3, "ATI Radeon RV280 (9200 SE)"}, + {0x1002, 0x5c60, 0x3, "ATI Radeon RV280"}, + {0x1002, 0x5c61, 0x3, "ATI Radeon RV280 Mobility"}, + {0x1002, 0x5c62, 0x3, "ATI Radeon RV280"}, + {0x1002, 0x5c63, 0x3, "ATI Radeon RV280 Mobility"}, + {0x1002, 0x5c64, 0x3, "ATI Radeon RV280"}, + {0, 0, 0, NULL} }; -struct pci_id_list r128_id_list[] = { - {0x1002, 0x4c45, "ATI Rage 128 LE"}, - {0x1002, 0x4c46, "ATI Rage 128 LF"}, - {0x1002, 0x4d46, "ATI Rage 128 MF"}, - {0x1002, 0x4d46, "ATI Rage 128 ML"}, - {0x1002, 0x5041, "ATI Rage 128 PA"}, - {0x1002, 0x5042, "ATI Rage 128 PB"}, - {0x1002, 0x5043, "ATI Rage 128 PC"}, - {0x1002, 0x5044, "ATI Rage 128 PD"}, - {0x1002, 0x5045, "ATI Rage 128 PE"}, - {0x1002, 0x5046, "ATI Rage 128 PF"}, - {0x1002, 0x5047, "ATI Rage 128 PG"}, - {0x1002, 0x5048, "ATI Rage 128 PH"}, - {0x1002, 0x5049, "ATI Rage 128 PI"}, - {0x1002, 0x504a, "ATI Rage 128 PJ"}, - {0x1002, 0x504b, "ATI Rage 128 PK"}, - {0x1002, 0x504c, "ATI Rage 128 PL"}, - {0x1002, 0x504d, "ATI Rage 128 PM"}, - {0x1002, 0x504e, "ATI Rage 128 PN"}, - {0x1002, 0x504f, "ATI Rage 128 PO"}, - {0x1002, 0x5050, "ATI Rage 128 PP"}, - {0x1002, 0x5051, "ATI Rage 128 PQ"}, - {0x1002, 0x5052, "ATI Rage 128 PR"}, - {0x1002, 0x5053, "ATI Rage 128 PS"}, - {0x1002, 0x5054, "ATI Rage 128 PT"}, - {0x1002, 0x5055, "ATI Rage 128 PU"}, - {0x1002, 0x5056, "ATI Rage 128 PV"}, - {0x1002, 0x5057, "ATI Rage 128 PW"}, - {0x1002, 0x5058, "ATI Rage 128 PX"}, - {0x1002, 0x5245, "ATI Rage 128 RE"}, - {0x1002, 0x5246, "ATI Rage 128 RF"}, - {0x1002, 0x5247, "ATI Rage 128 RG"}, - {0x1002, 0x524b, "ATI Rage 128 RK"}, - {0x1002, 0x524c, "ATI Rage 128 RL"}, - {0x1002, 0x5345, "ATI Rage 128 SE"}, - {0x1002, 0x5346, "ATI Rage 128 SF"}, - {0x1002, 0x5347, "ATI Rage 128 SG"}, - {0x1002, 0x5348, "ATI Rage 128 SH"}, - {0x1002, 0x534b, "ATI Rage 128 SK"}, - {0x1002, 0x534c, "ATI Rage 128 SL"}, - {0x1002, 0x534d, "ATI Rage 128 SM"}, - {0x1002, 0x534e, "ATI Rage 128 SN"}, - {0x1002, 0x5446, "ATI Rage 128 TF"}, - {0x1002, 0x544c, "ATI Rage 128 TL"}, - {0x1002, 0x5452, "ATI Rage 128 TR"}, - {0x1002, 0x5453, "ATI Rage 128 TS"}, - {0x1002, 0x5454, "ATI Rage 128 TT"}, - {0x1002, 0x5455, "ATI Rage 128 TU"}, - {0, 0, NULL} -}; +static char * +make_busid(KdCardAttr *attr) +{ + char *busid; + + busid = xalloc(20); + if (busid == NULL) + return NULL; + snprintf(busid, 20, "pci:%04x:%02x:%02x.%d", attr->domain, attr->bus, + attr->slot, attr->func); + return busid; +} static Bool ATICardInit(KdCardInfo *card) @@ -205,11 +215,28 @@ ATICardInit(KdCardInfo *card) return FALSE; } + atic->busid = make_busid(&card->attr); + if (atic->busid == NULL) + return FALSE; + +#ifdef USE_DRI + /* We demand identification by busid, not driver name */ + atic->drmFd = drmOpen(NULL, atic->busid); + if (atic->drmFd < 0) + ErrorF("Failed to open DRM. DMA won't be used.\n"); +#endif /* USE_DRI */ + card->driver = atic; - for (i = 0; radeon_id_list[i].name != NULL; i++) { - if (radeon_id_list[i].device == card->attr.deviceID) - atic->is_radeon = TRUE; + for (i = 0; ati_pci_ids[i].name != NULL; i++) { + struct pci_id_entry *id = &ati_pci_ids[i]; + if (id->device == card->attr.deviceID) { + if (id->caps & CAP_RADEON) { + if (id->caps & CAP_R200) + atic->is_r200 = TRUE; + atic->is_radeon = TRUE; + } + } } return TRUE; } @@ -227,15 +254,14 @@ static Bool ATIScreenInit(KdScreenInfo *screen) { ATIScreenInfo *atis; - ATICardInfo *atic = screen->card->driver; + ATICardInfo(screen); int success = FALSE; atis = xcalloc(sizeof(ATIScreenInfo), 1); if (atis == NULL) return FALSE; - if (screen->fb[0].depth == 0) - screen->fb[0].depth = 16; + atis->atic = atic; screen->driver = atis; diff --git a/hw/kdrive/ati/ati.h b/hw/kdrive/ati/ati.h index f713d8027..cacc264dd 100644 --- a/hw/kdrive/ati/ati.h +++ b/hw/kdrive/ati/ati.h @@ -35,8 +35,14 @@ #include <vesa.h> #endif +#ifdef XF86DRI +#define USE_DRI +#include "libdrm.h" +#include "dri.h" +#endif + #define RADEON_REG_BASE(c) ((c)->attr.address[1]) -#define RADEON_REG_SIZE(c) (0x10000) +#define RADEON_REG_SIZE(c) (0x4000) #ifdef __powerpc__ @@ -75,9 +81,14 @@ typedef volatile CARD8 VOL8; typedef volatile CARD16 VOL16; typedef volatile CARD32 VOL32; -struct pci_id_list { +#define CAP_RADEON 0x1 /* Whether it's a Radeon vs R128 */ +#define CAP_R200 0x2 /* If CAP_RADEON, whether it's an R200 */ +#define CAP_NODRM 0x4 /* Set if no initialization for the DRM yet. */ + +struct pci_id_entry { CARD16 vendor; CARD16 device; + CARD8 caps; char *name; }; @@ -107,8 +118,14 @@ typedef struct _ATICardInfo { } backend_priv; struct backend_funcs backend_funcs; + struct pci_id_entry *pci_id; CARD8 *reg_base; Bool is_radeon; + Bool is_r200; + char *busid; +#ifdef USE_DRI + int drmFd; +#endif /* USE_DRI */ Bool use_fbdev, use_vesa; } ATICardInfo; @@ -124,9 +141,89 @@ typedef struct _ATIScreenInfo { VesaScreenPrivRec vesa; #endif } backend_priv; + KaaScreenInfoRec kaa; + ATICardInfo *atic; + + Bool using_dri; + Bool using_dma; + +#ifdef USE_DRI + drmSize registerSize; + drmHandle registerHandle; + drmHandle fbHandle; + + int IsAGP; + drmSize gartSize; + drmHandle agpMemHandle; /* Handle from drmAgpAlloc */ + unsigned long gartOffset; + unsigned char *AGP; /* Map */ + int agpMode; + drmSize pciSize; + drmHandle pciMemHandle; + + /* 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 (MB) */ + unsigned char *ring; /* Map */ + + unsigned long ringReadOffset; /* Offset into AGP space */ + drmHandle ringReadPtrHandle; /* Handle from drmAddMap */ + drmSize ringReadMapSize; /* Size of map */ + unsigned char *ringReadPtr; /* Map */ + + /* vertex/indirect buffer data */ + unsigned long bufStart; /* Offset into AGP space */ + drmHandle bufHandle; /* Handle from drmAddMap */ + drmSize bufMapSize; /* Size of map */ + int bufSize; /* Size of buffers (MB) */ + unsigned char *buf; /* Map */ + int bufNumBufs; /* Number of buffers */ + drmBufMapPtr buffers; /* Buffer map */ + + /* AGP Texture data */ + unsigned long gartTexStart; /* Offset into AGP space */ + drmHandle gartTexHandle; /* Handle from drmAddMap */ + drmSize gartTexMapSize; /* Size of map */ + int gartTexSize; /* Size of AGP tex space (MB) */ + unsigned char *gartTex; /* Map */ + int log2GARTTexGran; - int datatype; - int dp_gui_master_cntl; + int CCEMode; /* CCE mode that server/clients use */ + int CPMode; /* CP mode that server/clients use */ + int CCEFifoSize; /* Size of the CCE command FIFO */ + int DMAusecTimeout; /* CCE timeout in usecs */ + + /* DMA 2D accleration */ + drmBufPtr indirectBuffer; + int indirectStart; + + /* DRI screen private data */ + int fbX; + int fbY; + int backX; + int backY; + int depthX; + int depthY; + + int frontOffset; + int frontPitch; + int backOffset; + int backPitch; + int depthOffset; + int depthPitch; + int spanOffset; + int textureOffset; + int textureSize; + int log2TexGran; + + int irqEnabled; + + int serverContext; + + DRIInfoPtr pDRIInfo; +#endif /* USE_DRI */ } ATIScreenInfo; #define getATIScreenInfo(kd) ((ATIScreenInfo *) ((kd)->screen->driver)) @@ -156,6 +253,14 @@ ATIDrawDisable(ScreenPtr pScreen); void ATIDrawFini(ScreenPtr pScreen); +#ifdef USE_DRI +Bool +ATIDRIScreenInit(ScreenPtr pScreen); + +void +ATIDRICloseScreen(ScreenPtr pScreen); +#endif /* USE_DRI */ + extern KdCardFuncs ATIFuncs; #endif /* _ATI_H_ */ diff --git a/hw/kdrive/ati/ati_draw.c b/hw/kdrive/ati/ati_draw.c index c1da03cbe..5dab41ede 100644 --- a/hw/kdrive/ati/ati_draw.c +++ b/hw/kdrive/ati/ati_draw.c @@ -28,6 +28,12 @@ #endif #include "ati.h" #include "ati_reg.h" +#include "ati_draw.h" +#ifdef USE_DRI +#include "radeon_common.h" +#include "r128_common.h" +#include "ati_sarea.h" +#endif /* USE_DRI */ CARD8 ATISolidRop[16] = { /* GXclear */ 0x00, /* 0 */ @@ -67,24 +73,57 @@ CARD8 ATIBltRop[16] = { /* GXset */ 0xff, /* 1 */ }; +static CARD32 R128BlendOp[] = { + /* Clear */ + R128_ALPHA_BLEND_SRC_ZERO | R128_ALPHA_BLEND_DST_ZERO, + /* Src */ + R128_ALPHA_BLEND_SRC_ONE | R128_ALPHA_BLEND_DST_ZERO, + /* Dst */ + R128_ALPHA_BLEND_SRC_ZERO | R128_ALPHA_BLEND_DST_ONE, + /* Over */ + R128_ALPHA_BLEND_SRC_ONE | R128_ALPHA_BLEND_DST_INVSRCALPHA, + /* OverReverse */ + R128_ALPHA_BLEND_SRC_INVDSTALPHA | R128_ALPHA_BLEND_DST_ONE, + /* In */ + R128_ALPHA_BLEND_SRC_DSTALPHA | R128_ALPHA_BLEND_DST_ZERO, + /* InReverse */ + R128_ALPHA_BLEND_SRC_ZERO | R128_ALPHA_BLEND_DST_SRCALPHA, + /* Out */ + R128_ALPHA_BLEND_SRC_INVDSTALPHA | R128_ALPHA_BLEND_DST_ZERO, + /* OutReverse */ + R128_ALPHA_BLEND_SRC_ZERO | R128_ALPHA_BLEND_DST_INVSRCALPHA, + /* Atop */ + R128_ALPHA_BLEND_SRC_DSTALPHA | R128_ALPHA_BLEND_DST_INVSRCALPHA, + /* AtopReverse */ + R128_ALPHA_BLEND_SRC_INVDSTALPHA | R128_ALPHA_BLEND_DST_SRCALPHA, + /* Xor */ + R128_ALPHA_BLEND_SRC_INVDSTALPHA | R128_ALPHA_BLEND_DST_INVSRCALPHA, + /* Add */ + R128_ALPHA_BLEND_SRC_ONE | R128_ALPHA_BLEND_DST_ONE, +}; + int copydx, copydy; -Bool is_radeon; +int fifo_size; +ATIScreenInfo *accel_atis; +int src_pitch; +int src_offset; +int src_bpp; /* If is_24bpp is set, then we are using the accelerator in 8-bit mode due * to it being broken for 24bpp, so coordinates have to be multiplied by 3. */ -Bool is_24bpp; -int fifo_size; -char *mmio; -CARD32 bltCmd; +int is_24bpp; static void -ATIWaitAvail(int n) +ATIWaitAvailMMIO(int n) { + ATICardInfo *atic = accel_atis->atic; + char *mmio = atic->reg_base; + if (fifo_size >= n) { fifo_size -= n; return; } - if (is_radeon) { + if (atic->is_radeon) { do { fifo_size = MMIO_IN32(mmio, RADEON_REG_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK; @@ -100,9 +139,25 @@ ATIWaitAvail(int n) static void RadeonWaitIdle(void) { + ATIScreenInfo *atis = accel_atis; + ATICardInfo *atic = atis->atic; + char *mmio = atic->reg_base; CARD32 temp; + +#ifdef USE_DRI + if (atis->using_dma) { + int ret; + + do { + ret = drmCommandNone(atic->drmFd, DRM_RADEON_CP_IDLE); + } while (ret == -EBUSY); + if (ret != 0) + ErrorF("Failed to idle DMA, returned %d\n", ret); + } +#endif /* USE_DRI */ + /* Wait for the engine to go idle */ - ATIWaitAvail(64); + ATIWaitAvailMMIO(64); while ((MMIO_IN32(mmio, RADEON_REG_RBBM_STATUS) & RADEON_RBBM_ACTIVE) != 0) @@ -121,10 +176,25 @@ RadeonWaitIdle(void) static void R128WaitIdle(void) { + ATIScreenInfo *atis = accel_atis; + ATICardInfo *atic = atis->atic; + char *mmio = atic->reg_base; CARD32 temp; int tries; - ATIWaitAvail(64); +#ifdef USE_DRI + if (atis->using_dma) { + int ret; + + do { + ret = drmCommandNone(atic->drmFd, DRM_R128_CCE_IDLE); + } while (ret == -EBUSY); + if (ret != 0) + ErrorF("Failed to idle DMA, returned %d\n", ret); + } +#endif /* USE_DRI */ + + ATIWaitAvailMMIO(64); tries = 1000000; while (tries--) { @@ -146,170 +216,199 @@ R128WaitIdle(void) static void ATIWaitIdle(void) { - if (is_radeon) + ATIScreenInfo *atis = accel_atis; + ATICardInfo *atic = atis->atic; + +#ifdef USE_DRI + /* Dispatch any accumulated commands first. */ + if (atis->using_dma && atis->indirectBuffer != NULL) + ATIDMAFlushIndirect(0); +#endif /* USE_DRI */ + + if (atic->is_radeon) RadeonWaitIdle(); else R128WaitIdle(); } -static Bool -ATISetup(PixmapPtr pDst, PixmapPtr pSrc) +#ifdef USE_DRI +void ATIDMAStart(ScreenPtr pScreen) { - KdScreenPriv(pDst->drawable.pScreen); + KdScreenPriv(pScreen); ATICardInfo(pScreenPriv); - int dst_offset, dst_pitch, src_offset = 0, src_pitch = 0; - int bpp = pScreenPriv->screen->fb[0].bitsPerPixel; - - mmio = atic->reg_base; - - /* No acceleration for other formats (yet) */ - if (pDst->drawable.bitsPerPixel != bpp) - return FALSE; - - dst_pitch = pDst->devKind; - dst_offset = ((CARD8 *)pDst->devPrivate.ptr - - pScreenPriv->screen->memory_base); - if (pSrc != NULL) { - src_pitch = pSrc->devKind; - src_offset = ((CARD8 *)pSrc->devPrivate.ptr - - pScreenPriv->screen->memory_base); - } + ATIScreenInfo(pScreenPriv); + int ret; - ATIWaitAvail((pSrc != NULL) ? 3 : 2); - if (is_radeon) { - MMIO_OUT32(mmio, RADEON_REG_DST_PITCH_OFFSET, - ((dst_pitch >> 6) << 22) | (dst_offset >> 10)); - if (pSrc != NULL) { - MMIO_OUT32(mmio, RADEON_REG_SRC_PITCH_OFFSET, - ((src_pitch >> 6) << 22) | (src_offset >> 10)); - } - } else { - if (is_24bpp) { - dst_pitch *= 3; - src_pitch *= 3; - } - /* R128 pitch is in units of 8 pixels, offset in 32 bytes */ - MMIO_OUT32(mmio, RADEON_REG_DST_PITCH_OFFSET, - ((dst_pitch/bpp) << 21) | (dst_offset >> 5)); - if (pSrc != NULL) { - MMIO_OUT32(mmio, RADEON_REG_SRC_PITCH_OFFSET, - ((src_pitch/bpp) << 21) | (src_offset >> 5)); - } - } - MMIO_OUT32(mmio, RADEON_REG_DEFAULT_SC_BOTTOM_RIGHT, - (RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX)); + if (atic->is_radeon) + ret = drmCommandNone(atic->drmFd, DRM_RADEON_CP_START); + else + ret = drmCommandNone(atic->drmFd, DRM_R128_CCE_START); - return TRUE; + if (ret == 0) + atis->using_dma = TRUE; + else + ErrorF("%s: DMA start returned %d\n", __FUNCTION__, ret); } -static Bool -ATIPrepareSolid(PixmapPtr pPixmap, int alu, Pixel pm, Pixel fg) +/* Attempts to idle the DMA engine, and stops it. Note that the ioctl is the + * same for both R128 and Radeon, so we can just use the name of one of them. + */ +void ATIDMAStop(ScreenPtr pScreen) { - KdScreenPriv(pPixmap->drawable.pScreen); + KdScreenPriv(pScreen); + ATICardInfo(pScreenPriv); ATIScreenInfo(pScreenPriv); + drmRadeonCPStop stop; + int ret; - if (is_24bpp) { - if (pm != 0xffffffff) - return FALSE; - /* Solid fills in fake-24bpp mode only work if the pixel color - * is all the same byte. - */ - if ((fg & 0xffffff) != (((fg & 0xff) << 16) | ((fg >> 8) & - 0xffff))) - return FALSE; - } + stop.flush = 1; + stop.idle = 1; + ret = drmCommandWrite(atic->drmFd, DRM_RADEON_CP_STOP, &stop, + sizeof(drmRadeonCPStop)); - if (!ATISetup(pPixmap, NULL)) - return FALSE; + if (ret != 0 && errno == EBUSY) { + ErrorF("Failed to idle the DMA engine\n"); - ATIWaitAvail(4); - MMIO_OUT32(mmio, RADEON_REG_DP_GUI_MASTER_CNTL, - atis->dp_gui_master_cntl | - RADEON_GMC_BRUSH_SOLID_COLOR | - RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_SRC_DATATYPE_COLOR | - (ATISolidRop[alu] << 16)); - MMIO_OUT32(mmio, RADEON_REG_DP_BRUSH_FRGD_CLR, fg); - MMIO_OUT32(mmio, RADEON_REG_DP_WRITE_MASK, pm); - MMIO_OUT32(mmio, RADEON_REG_DP_CNTL, RADEON_DST_X_LEFT_TO_RIGHT | - RADEON_DST_Y_TOP_TO_BOTTOM); + stop.idle = 0; + ret = drmCommandWrite(atic->drmFd, DRM_RADEON_CP_STOP, &stop, + sizeof(drmRadeonCPStop)); + } + atis->using_dma = FALSE; +} - return TRUE; +/* The R128 and Radeon Indirect ioctls differ only in the ioctl number */ +void ATIDMADispatchIndirect(Bool discard) +{ + ATIScreenInfo *atis = accel_atis; + ATICardInfo *atic = atis->atic; + drmBufPtr buffer = atis->indirectBuffer; + drmR128Indirect indirect; + int cmd; + + indirect.idx = buffer->idx; + indirect.start = atis->indirectStart; + indirect.end = buffer->used; + indirect.discard = discard; + cmd = atic->is_radeon ? DRM_RADEON_INDIRECT : DRM_R128_INDIRECT; + drmCommandWriteRead(atic->drmFd, cmd, &indirect, + sizeof(drmR128Indirect)); } -static void -ATISolid(int x1, int y1, int x2, int y2) +/* Flush the indirect buffer to the kernel for submission to the card */ +void ATIDMAFlushIndirect(Bool discard) { - if (is_24bpp) { - x1 *= 3; - x2 *= 3; + ATIScreenInfo *atis = accel_atis; + drmBufPtr buffer = atis->indirectBuffer; + + if (buffer == NULL) + return; + if ((atis->indirectStart == buffer->used) && !discard) + return; + + ATIDMADispatchIndirect(discard); + + if (discard) { + atis->indirectBuffer = ATIDMAGetBuffer(); + atis->indirectStart = 0; + } else { + /* Start on a double word boundary */ + atis->indirectStart = buffer->used = (buffer->used + 7) & ~7; } - ATIWaitAvail(2); - MMIO_OUT32(mmio, RADEON_REG_DST_Y_X, (y1 << 16) | x1); - MMIO_OUT32(mmio, RADEON_REG_DST_WIDTH_HEIGHT, ((x2 - x1) << 16) | - (y2 - y1)); } -static void -ATIDoneSolid(void) +/* Get an indirect buffer for the DMA 2D acceleration commands */ +drmBufPtr ATIDMAGetBuffer() { + ATIScreenInfo *atis = accel_atis; + ATICardInfo *atic = atis->atic; + drmDMAReq dma; + drmBufPtr buf = NULL; + int indx = 0; + int size = 0; + int ret; + + dma.context = atis->serverContext; + dma.send_count = 0; + dma.send_list = NULL; + dma.send_sizes = NULL; + dma.flags = 0; + dma.request_count = 1; + if (atis->atic->is_radeon) + dma.request_size = RADEON_BUFFER_SIZE; + else + dma.request_size = R128_BUFFER_SIZE; + dma.request_list = &indx; + dma.request_sizes = &size; + dma.granted_count = 0; + + do { + ret = drmDMA(atic->drmFd, &dma); + } while (ret != 0); + + buf = &atis->buffers->list[indx]; + buf->used = 0; + return buf; } +#endif /* USE_DRI */ static Bool -ATIPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu, Pixel pm) +R128GetDatatypePict(CARD32 format, CARD32 *type) { - KdScreenPriv(pDst->drawable.pScreen); - ATIScreenInfo(pScreenPriv); - - copydx = dx; - copydy = dy; - - if (is_24bpp && pm != 0xffffffff) - return FALSE; - - if (!ATISetup(pDst, pSrc)) - return FALSE; + switch (format) { + case PICT_a8r8g8b8: + *type = R128_DATATYPE_ARGB_8888; + return TRUE; + case PICT_r5g6b5: + *type = R128_DATATYPE_RGB_565; + return TRUE; + } - ATIWaitAvail(3); - MMIO_OUT32(mmio, RADEON_REG_DP_GUI_MASTER_CNTL, - atis->dp_gui_master_cntl | - RADEON_GMC_BRUSH_SOLID_COLOR | - RADEON_GMC_SRC_DATATYPE_COLOR | - (ATIBltRop[alu] << 16) | - RADEON_GMC_SRC_PITCH_OFFSET_CNTL | - RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_DP_SRC_SOURCE_MEMORY); - MMIO_OUT32(mmio, RADEON_REG_DP_WRITE_MASK, pm); - MMIO_OUT32(mmio, RADEON_REG_DP_CNTL, - (dx >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) | - (dy >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0)); + ErrorF ("Unsupported format: %x\n", format); - return TRUE; + return FALSE; } -static void -ATICopy(int srcX, int srcY, int dstX, int dstY, int w, int h) +/* Assumes that depth 15 and 16 can be used as depth 16, which is okay since we + * require src and dest datatypes to be equal. + */ +static Bool +ATIGetDatatypeBpp(int bpp, CARD32 *type) { - if (is_24bpp) { - srcX *= 3; - dstX *= 3; - w *= 3; - } + is_24bpp = FALSE; - if (copydx < 0) { - srcX += w - 1; - dstX += w - 1; + switch (bpp) { + case 8: + *type = R128_DATATYPE_C8; + return TRUE; + case 16: + *type = R128_DATATYPE_RGB_565; + return TRUE; + case 24: + *type = R128_DATATYPE_C8; + is_24bpp = TRUE; + return TRUE; + case 32: + *type = R128_DATATYPE_ARGB_8888; + return TRUE; + default: + ErrorF("Unsupported bpp: %x\n", bpp); + return FALSE; } +} - if (copydy < 0) { - srcY += h - 1; - dstY += h - 1; - } +#ifdef USE_DRI +#define USE_DMA +#include "ati_drawtmp.h" +#include "r128_blendtmp.h" +#endif /* USE_DRI */ - ATIWaitAvail(3); - MMIO_OUT32(mmio, RADEON_REG_SRC_Y_X, (srcY << 16) | srcX); - MMIO_OUT32(mmio, RADEON_REG_DST_Y_X, (dstY << 16) | dstX); - MMIO_OUT32(mmio, RADEON_REG_DST_HEIGHT_WIDTH, (h << 16) | w); +#undef USE_DMA +#include "ati_drawtmp.h" +#include "r128_blendtmp.h" + +static void +ATIDoneSolid(void) +{ } static void @@ -317,20 +416,6 @@ ATIDoneCopy(void) { } -static KaaScreenInfoRec ATIKaa = { - ATIPrepareSolid, - ATISolid, - ATIDoneSolid, - - ATIPrepareCopy, - ATICopy, - ATIDoneCopy, - - 0, /* offscreenByteAlign */ - 0, /* offscreenPitch */ - KAA_OFFSCREEN_PIXMAPS, /* flags */ -}; - Bool ATIDrawInit(ScreenPtr pScreen) { @@ -338,50 +423,57 @@ ATIDrawInit(ScreenPtr pScreen) ATIScreenInfo(pScreenPriv); ATICardInfo(pScreenPriv); - is_radeon = atic->is_radeon; - is_24bpp = FALSE; - - switch (pScreenPriv->screen->fb[0].depth) + ErrorF("Screen: %d/%d depth/bpp\n", pScreenPriv->screen->fb[0].depth, + pScreenPriv->screen->fb[0].bitsPerPixel); +#ifdef USE_DRI + if (atis->using_dri) + ATIDMAStart(pScreen); + else { + if (ATIDRIScreenInit(pScreen)) + atis->using_dri = TRUE; + } +#endif /* USE_DRI */ + + memset(&atis->kaa, 0, sizeof(KaaScreenInfoRec)); +#ifdef USE_DRI + if (atis->using_dma) { + atis->kaa.PrepareSolid = ATIPrepareSolidDMA; + atis->kaa.Solid = ATISolidDMA; + atis->kaa.PrepareCopy = ATIPrepareCopyDMA; + atis->kaa.Copy = ATICopyDMA; + if (!atic->is_radeon) { + atis->kaa.PrepareBlend = R128PrepareBlendDMA; + atis->kaa.Blend = R128BlendDMA; + atis->kaa.DoneBlend = R128DoneBlendDMA; + } + } else { +#else { - case 8: - atis->datatype = 2; - break; - case 15: - atis->datatype = 3; - break; - case 16: - atis->datatype = 4; - break; - case 24: - if (pScreenPriv->screen->fb[0].bitsPerPixel == 24) { - is_24bpp = TRUE; - atis->datatype = 2; - } else { - atis->datatype = 6; +#endif /* USE_DRI */ + atis->kaa.PrepareSolid = ATIPrepareSolidMMIO; + atis->kaa.Solid = ATISolidMMIO; + atis->kaa.PrepareCopy = ATIPrepareCopyMMIO; + atis->kaa.Copy = ATICopyMMIO; + if (!atic->is_radeon) { + atis->kaa.PrepareBlend = R128PrepareBlendMMIO; + atis->kaa.Blend = R128BlendMMIO; + atis->kaa.DoneBlend = R128DoneBlendMMIO; } - break; - default: - FatalError("[ati]: depth %d unsupported\n", - pScreenPriv->screen->fb[0].depth); - return FALSE; } - - atis->dp_gui_master_cntl = (atis->datatype << 8) | - RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_AUX_CLIP_DIS; - - if (is_radeon) { - ATIKaa.offscreenByteAlign = 1024; - ATIKaa.offscreenPitch = 1024; + atis->kaa.DoneSolid = ATIDoneSolid; + atis->kaa.DoneCopy = ATIDoneCopy; + atis->kaa.flags = KAA_OFFSCREEN_PIXMAPS; + if (atic->is_radeon) { + atis->kaa.offscreenByteAlign = 1024; + atis->kaa.offscreenPitch = 1024; } else { - ATIKaa.offscreenByteAlign = 8; - /* Workaround for corrupation at 8 and 24bpp. Why? */ - if (atis->datatype == 2) - ATIKaa.offscreenPitch = 16; - else - ATIKaa.offscreenPitch = - pScreenPriv->screen->fb[0].bitsPerPixel; + atis->kaa.offscreenByteAlign = 32; + /* Pitch alignment is in sets of 8 pixels, and we need to cover + * 32bpp, so 32 bytes. + */ + atis->kaa.offscreenPitch = 32; } - if (!kaaDrawInit(pScreen, &ATIKaa)) + if (!kaaDrawInit(pScreen, &atis->kaa)) return FALSE; return TRUE; @@ -401,15 +493,27 @@ ATIDrawDisable(ScreenPtr pScreen) void ATIDrawFini(ScreenPtr pScreen) { +#ifdef USE_DRI + KdScreenPriv(pScreen); + ATIScreenInfo(pScreenPriv); + + if (atis->using_dma) + ATIDMAStop(pScreen); + + if (atis->using_dri) + ATIDRICloseScreen(pScreen); +#endif /* USE_DRI */ + + kaaDrawFini(pScreen); } void ATIDrawSync(ScreenPtr pScreen) { KdScreenPriv(pScreen); - ATICardInfo(pScreenPriv); + ATIScreenInfo(pScreenPriv); - mmio = atic->reg_base; + accel_atis = atis; ATIWaitIdle(); } diff --git a/hw/kdrive/ati/ati_draw.h b/hw/kdrive/ati/ati_draw.h new file mode 100644 index 000000000..eddc8721e --- /dev/null +++ b/hw/kdrive/ati/ati_draw.h @@ -0,0 +1,82 @@ +/* + * $Id$ + * + * Copyright © 2003 Eric Anholt + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Eric Anholt not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Eric Anholt makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ERIC ANHOLT 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. + */ +/* $Header$ */ + +#ifndef _ATI_DRAW_H_ +#define _ATI_DRAW_H_ + +#ifdef USE_DRI + +#define DMA_PACKET0( reg, n ) \ + (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) + +#define RING_LOCALS CARD32 *__head; int __count; + +#define BEGIN_RING( n ) \ +do { \ + if (atis->indirectBuffer == NULL) { \ + atis->indirectBuffer = ATIDMAGetBuffer(); \ + atis->indirectStart = 0; \ + } else if ((atis->indirectBuffer->used + 4*(n)) > \ + atis->indirectBuffer->total) { \ + ATIDMAFlushIndirect(1); \ + } \ + __head = (pointer)((char *)atis->indirectBuffer->address + \ + atis->indirectBuffer->used); \ + __count = 0; \ +} while (0) + +#define ADVANCE_RING() do { \ + atis->indirectBuffer->used += __count * (int)sizeof(CARD32); \ +} while (0) + +#define OUT_RING(x) do { \ + MMIO_OUT32(&__head[__count++], 0, (x)); \ +} while (0) + +#define OUT_RING_REG(reg, val) \ +do { \ + OUT_RING(DMA_PACKET0(reg, 0)); \ + OUT_RING(val); \ +} while (0) + +drmBufPtr ATIDMAGetBuffer(void); +void ATIDMAFlushIndirect(Bool discard); +void ATIDMADispatchIndirect(Bool discard); +void ATIDMAStart(ScreenPtr pScreen); +void ATIDMAStop(ScreenPtr pScreen); + +#endif /* USE_DRI */ + +#if 0 +#define ATI_FALLBACK(x) \ +do { \ + ErrorF x; \ + return FALSE; \ +} while (0) +#else +#define ATI_FALLBACK(x) return FALSE +#endif + +#endif /* _ATI_DRAW_H_ */ diff --git a/hw/kdrive/ati/ati_drawtmp.h b/hw/kdrive/ati/ati_drawtmp.h new file mode 100644 index 000000000..03f88a700 --- /dev/null +++ b/hw/kdrive/ati/ati_drawtmp.h @@ -0,0 +1,241 @@ +/* + * $Id$ + * + * Copyright © 2003 Eric Anholt + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Eric Anholt not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Eric Anholt makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ERIC ANHOLT 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. + */ +/* $Header$ */ + +#ifdef USE_DMA +#define TAG(x) x##DMA +#define LOCALS RING_LOCALS; \ + (void)atic +#define BEGIN(x) BEGIN_RING(x * 2) +#define OUT_REG(reg, val) OUT_RING_REG(reg, val) +#define END() ADVANCE_RING() +#else +#define TAG(x) x##MMIO +#define LOCALS char *mmio = atic->reg_base; \ + (void)atis +#define BEGIN(x) ATIWaitAvailMMIO(x) +#define OUT_REG(reg, val) MMIO_OUT32((mmio), (reg), (val)) +#define END() +#endif + +static Bool +TAG(ATISetup)(PixmapPtr pDst, PixmapPtr pSrc) +{ + KdScreenPriv(pDst->drawable.pScreen); + ATIScreenInfo(pScreenPriv); + ATICardInfo(pScreenPriv); + int dst_offset, dst_pitch; + int bpp = pDst->drawable.bitsPerPixel; + LOCALS; + + accel_atis = atis; + + dst_pitch = pDst->devKind; + dst_offset = ((CARD8 *)pDst->devPrivate.ptr - + pScreenPriv->screen->memory_base); + if ((dst_pitch & (atis->kaa.offscreenPitch - 1)) != 0) + ATI_FALLBACK(("Bad dst pitch 0x%x\n", dst_pitch)); + if ((dst_offset & (atis->kaa.offscreenByteAlign - 1)) != 0) + ATI_FALLBACK(("Bad dst offset 0x%x\n", dst_offset)); + + if (pSrc != NULL) { + src_pitch = pSrc->devKind; + src_offset = ((CARD8 *)pSrc->devPrivate.ptr - + pScreenPriv->screen->memory_base); + if ((src_pitch & (atis->kaa.offscreenPitch - 1)) != 0) + ATI_FALLBACK(("Bad src pitch 0x%x\n", src_pitch)); + if ((src_offset & (atis->kaa.offscreenByteAlign - 1)) != 0) + ATI_FALLBACK(("Bad src offset 0x%x\n", src_offset)); + } + + BEGIN((pSrc != NULL) ? 3 : 2); + if (atic->is_radeon) { + OUT_REG(RADEON_REG_DST_PITCH_OFFSET, + ((dst_pitch >> 6) << 22) | (dst_offset >> 10)); + if (pSrc != NULL) { + OUT_REG(RADEON_REG_SRC_PITCH_OFFSET, + ((src_pitch >> 6) << 22) | (src_offset >> 10)); + } + } else { + if (is_24bpp) { + dst_pitch *= 3; + src_pitch *= 3; + } + /* R128 pitch is in units of 8 pixels, offset in 32 bytes */ + OUT_REG(RADEON_REG_DST_PITCH_OFFSET, + ((dst_pitch/bpp) << 21) | (dst_offset >> 5)); + if (pSrc != NULL) { + OUT_REG(RADEON_REG_SRC_PITCH_OFFSET, + ((src_pitch/bpp) << 21) | (src_offset >> 5)); + } + } + OUT_REG(RADEON_REG_DEFAULT_SC_BOTTOM_RIGHT, + (RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX)); + END(); + + return TRUE; +} + +static Bool +TAG(ATIPrepareSolid)(PixmapPtr pPixmap, int alu, Pixel pm, Pixel fg) +{ + KdScreenPriv(pPixmap->drawable.pScreen); + ATIScreenInfo(pScreenPriv); + ATICardInfo(pScreenPriv); + CARD32 datatype; + LOCALS; + + if (is_24bpp) { + /* Solid fills in fake-24bpp mode only work if the pixel color + * and planemask are all the same byte. + */ + if ((fg & 0xffffff) != (((fg & 0xff) << 16) | ((fg >> 8) & + 0xffff))) + ATI_FALLBACK(("Can't do solid color %d in 24bpp\n")); + if ((pm & 0xffffff) != (((pm & 0xff) << 16) | ((pm >> 8) & + 0xffff))) + ATI_FALLBACK(("Can't do planemask %d in 24bpp\n")); + } + + if (!ATIGetDatatypeBpp(pPixmap->drawable.bitsPerPixel, &datatype)) + return FALSE; + if (!TAG(ATISetup)(pPixmap, NULL)) + return FALSE; + + BEGIN(4); + OUT_REG(RADEON_REG_DP_GUI_MASTER_CNTL, + (datatype << 8) | + RADEON_GMC_CLR_CMP_CNTL_DIS | + RADEON_GMC_AUX_CLIP_DIS | + RADEON_GMC_BRUSH_SOLID_COLOR | + RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_SRC_DATATYPE_COLOR | + (ATISolidRop[alu] << 16)); + OUT_REG(RADEON_REG_DP_BRUSH_FRGD_CLR, fg); + OUT_REG(RADEON_REG_DP_WRITE_MASK, pm); + OUT_REG(RADEON_REG_DP_CNTL, RADEON_DST_X_LEFT_TO_RIGHT | + RADEON_DST_Y_TOP_TO_BOTTOM); + END(); + + return TRUE; +} + +static void +TAG(ATISolid)(int x1, int y1, int x2, int y2) +{ + ATIScreenInfo *atis = accel_atis; + ATICardInfo *atic = atis->atic; + LOCALS; + + if (is_24bpp) { + x1 *= 3; + x2 *= 3; + } + BEGIN(2); + OUT_REG(RADEON_REG_DST_Y_X, (y1 << 16) | x1); + OUT_REG(RADEON_REG_DST_WIDTH_HEIGHT, ((x2 - x1) << 16) | (y2 - y1)); + END(); +} + +static Bool +TAG(ATIPrepareCopy)(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu, Pixel pm) +{ + KdScreenPriv(pDst->drawable.pScreen); + ATIScreenInfo(pScreenPriv); + ATICardInfo(pScreenPriv); + CARD32 datatype; + LOCALS; + + /* No acceleration between different formats */ + if (pSrc->drawable.bitsPerPixel != pDst->drawable.bitsPerPixel) + ATI_FALLBACK(("src bpp != dst bpp (%d vs %d)\n", + pSrc->drawable.bitsPerPixel, pDst->drawable.bitsPerPixel)); + + copydx = dx; + copydy = dy; + + if (is_24bpp && ((pm & 0xffffff) != (((pm & 0xff) << 16) | ((pm >> 8) & + 0xffff)))) + ATI_FALLBACK(("Can't do planemask %d in 24bpp\n")); + + if (!ATIGetDatatypeBpp(pDst->drawable.bitsPerPixel, &datatype)) + return FALSE; + if (!TAG(ATISetup)(pDst, pSrc)) + return FALSE; + + BEGIN(3); + OUT_REG(RADEON_REG_DP_GUI_MASTER_CNTL, + (datatype << 8) | + RADEON_GMC_CLR_CMP_CNTL_DIS | + RADEON_GMC_AUX_CLIP_DIS | + RADEON_GMC_BRUSH_SOLID_COLOR | + RADEON_GMC_SRC_DATATYPE_COLOR | + (ATIBltRop[alu] << 16) | + RADEON_GMC_SRC_PITCH_OFFSET_CNTL | + RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_DP_SRC_SOURCE_MEMORY); + OUT_REG(RADEON_REG_DP_WRITE_MASK, pm); + OUT_REG(RADEON_REG_DP_CNTL, + (dx >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) | + (dy >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0)); + END(); + + return TRUE; +} + +static void +TAG(ATICopy)(int srcX, int srcY, int dstX, int dstY, int w, int h) +{ + ATIScreenInfo *atis = accel_atis; + ATICardInfo *atic = atis->atic; + LOCALS; + + if (is_24bpp) { + srcX *= 3; + dstX *= 3; + w *= 3; + } + + if (copydx < 0) { + srcX += w - 1; + dstX += w - 1; + } + + if (copydy < 0) { + srcY += h - 1; + dstY += h - 1; + } + + BEGIN(3); + OUT_REG(RADEON_REG_SRC_Y_X, (srcY << 16) | srcX); + OUT_REG(RADEON_REG_DST_Y_X, (dstY << 16) | dstX); + OUT_REG(RADEON_REG_DST_HEIGHT_WIDTH, (h << 16) | w); + END(); +} + +#undef TAG +#undef LOCALS +#undef BEGIN +#undef OUT_REG +#undef END diff --git a/hw/kdrive/ati/ati_dri.c b/hw/kdrive/ati/ati_dri.c new file mode 100644 index 000000000..65ca0f72e --- /dev/null +++ b/hw/kdrive/ati/ati_dri.c @@ -0,0 +1,929 @@ +/* + * $Id$ + * + * Copyright © 2003 Eric Anholt + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Eric Anholt not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Eric Anholt makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ERIC ANHOLT 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. + */ +/* $Header$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "ati.h" +#include "ati_reg.h" +#include "ati_dri.h" +#include "ati_dripriv.h" +#include "sarea.h" +#include "ati_sarea.h" +#include "ati_draw.h" +#include "r128_common.h" +#include "radeon_common.h" + +/* ?? HACK - for now, put this here... */ +/* ?? Alpha - this may need to be a variable to handle UP1x00 vs TITAN */ +#if defined(__alpha__) +# define DRM_PAGE_SIZE 8192 +#elif defined(__ia64__) +# define DRM_PAGE_SIZE getpagesize() +#else +# define DRM_PAGE_SIZE 4096 +#endif + +void XFree86DRIExtensionInit(void); + +static Bool ATIDRIFinishScreenInit(ScreenPtr pScreen); + +/* Compute log base 2 of val. */ +static int +ATILog2(int val) +{ + int bits; + + if (!val) + return 1; + for (bits = 0; val != 0; val >>= 1, ++bits) + ; + return bits; +} + +static void +ATIDRIInitGARTValues(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + ATIScreenInfo(pScreenPriv); + int s, l; + + atis->gartOffset = 0; + + /* Initialize the ring buffer data */ + atis->ringStart = atis->gartOffset; + atis->ringMapSize = atis->ringSize*1024*1024 + DRM_PAGE_SIZE; + + atis->ringReadOffset = atis->ringStart + atis->ringMapSize; + atis->ringReadMapSize = DRM_PAGE_SIZE; + + /* Reserve space for vertex/indirect buffers */ + atis->bufStart = atis->ringReadOffset + atis->ringReadMapSize; + atis->bufMapSize = atis->bufSize*1024*1024; + + /* Reserve the rest for GART textures */ + atis->gartTexStart = atis->bufStart + atis->bufMapSize; + s = (atis->gartSize*1024*1024 - atis->gartTexStart); + l = ATILog2((s-1) / ATI_NR_TEX_REGIONS); + if (l < ATI_LOG_TEX_GRANULARITY) l = ATI_LOG_TEX_GRANULARITY; + atis->gartTexMapSize = (s >> l) << l; + atis->log2GARTTexGran = l; +} + +static int +ATIDRIAddAndMap(int fd, drmHandle offset, drmSize size, + drmMapType type, drmMapFlags flags, drmHandlePtr handle, + drmAddressPtr address, char *desc) +{ + char *name; + + name = (type == DRM_AGP) ? "agp" : "pci"; + + if (drmAddMap(fd, offset, size, type, flags, handle) < 0) { + ErrorF("[%s] Could not add %s mapping\n", name, desc); + return FALSE; + } + ErrorF("[%s] %s handle = 0x%08lx\n", name, desc, *handle); + + if (drmMap(fd, *handle, size, address) < 0) { + ErrorF("[agp] Could not map %s\n", name, desc); + return FALSE; + } + ErrorF("[%s] %s mapped at 0x%08lx\n", name, desc, address); + + return TRUE; +} + +/* Initialize the AGP state. Request memory for use in AGP space, and + initialize the Rage 128 registers to point to that memory. */ +static Bool +ATIDRIAgpInit(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + ATIScreenInfo(pScreenPriv); + ATICardInfo(pScreenPriv); + unsigned char *mmio = atic->reg_base; + unsigned long mode; + int ret; + unsigned long agpBase; + CARD32 cntl, chunk; + + if (drmAgpAcquire(atic->drmFd) < 0) { + ErrorF("[agp] AGP not available\n"); + return FALSE; + } + + ATIDRIInitGARTValues(pScreen); + + /* Modify the mode if the default mode is not appropriate for this + * particular combination of graphics card and AGP chipset. + */ + + /* XXX: Disable fast writes? */ + + mode = drmAgpGetMode(atic->drmFd); + if (mode > 4) + mode = 4; + /* Set all mode bits below the chosen one so fallback can happen */ + mode = (mode * 2) - 1; + + if (drmAgpEnable(atic->drmFd, mode) < 0) { + ErrorF("[agp] AGP not enabled\n"); + drmAgpRelease(atic->drmFd); + return FALSE; + } + + /* Workaround for some hardware bugs */ + /* XXX: Magic numbers */ + if (!atic->is_r200) { + cntl = MMIO_IN32(mmio, RADEON_REG_AGP_CNTL) | 0x000e0000; + MMIO_OUT32(mmio, RADEON_REG_AGP_CNTL, cntl); + } + + if ((ret = drmAgpAlloc(atic->drmFd, atis->gartSize*1024*1024, 0, NULL, + &atis->agpMemHandle)) < 0) { + ErrorF("[agp] Out of memory (%d)\n", ret); + drmAgpRelease(atic->drmFd); + return FALSE; + } + ErrorF("[agp] %d kB allocated with handle 0x%08lx\n", + atis->gartSize*1024, (long)atis->agpMemHandle); + + if (drmAgpBind(atic->drmFd, atis->agpMemHandle, atis->gartOffset) < 0) { + ErrorF("[agp] Could not bind\n"); + drmAgpFree(atic->drmFd, atis->agpMemHandle); + drmAgpRelease(atic->drmFd); + return FALSE; + } + + if (!ATIDRIAddAndMap(atic->drmFd, atis->ringStart, atis->ringMapSize, + DRM_AGP, DRM_READ_ONLY, &atis->ringHandle, + (drmAddressPtr)&atis->ring, "ring")) + return FALSE; + + if (!ATIDRIAddAndMap(atic->drmFd, atis->ringReadOffset, + atis->ringReadMapSize, DRM_AGP, DRM_READ_ONLY, + &atis->ringReadPtrHandle, (drmAddressPtr)&atis->ringReadPtr, + "ring read ptr")) + return FALSE; + + if (!ATIDRIAddAndMap(atic->drmFd, atis->bufStart, atis->bufMapSize, + DRM_AGP, 0, &atis->bufHandle, (drmAddressPtr)&atis->buf, + "vertex/indirect buffers")) + return FALSE; + + if (!ATIDRIAddAndMap(atic->drmFd, atis->gartTexStart, + atis->gartTexMapSize, DRM_AGP, 0, &atis->gartTexHandle, + (drmAddressPtr)&atis->gartTex, "AGP texture map")) + return FALSE; + + /* Initialize radeon/r128 AGP registers */ + cntl = MMIO_IN32(mmio, RADEON_REG_AGP_CNTL); + cntl &= ~RADEON_AGP_APER_SIZE_MASK; + switch (atis->gartSize) { + case 256: cntl |= RADEON_AGP_APER_SIZE_256MB; break; + case 128: cntl |= RADEON_AGP_APER_SIZE_128MB; break; + case 64: cntl |= RADEON_AGP_APER_SIZE_64MB; break; + case 32: cntl |= RADEON_AGP_APER_SIZE_32MB; break; + case 16: cntl |= RADEON_AGP_APER_SIZE_16MB; break; + case 8: cntl |= RADEON_AGP_APER_SIZE_8MB; break; + case 4: cntl |= RADEON_AGP_APER_SIZE_4MB; break; + default: + ErrorF("[agp] Illegal aperture size %d kB\n", atis->gartSize*1024); + return FALSE; + } + agpBase = drmAgpBase(atic->drmFd); + MMIO_OUT32(mmio, RADEON_REG_AGP_BASE, agpBase); + MMIO_OUT32(mmio, RADEON_REG_AGP_CNTL, cntl); + + if (!atic->is_radeon) { + /* Disable Rage 128 PCIGART registers */ + chunk = MMIO_IN32(mmio, R128_REG_BM_CHUNK_0_VAL); + chunk &= ~(R128_BM_PTR_FORCE_TO_PCI | + R128_BM_PM4_RD_FORCE_TO_PCI | + R128_BM_GLOBAL_FORCE_TO_PCI); + MMIO_OUT32(mmio, R128_REG_BM_CHUNK_0_VAL, chunk); + + /* Ensure AGP GART is used (for now) */ + MMIO_OUT32(mmio, R128_REG_PCI_GART_PAGE, 1); + } + + return TRUE; +} + +static Bool +ATIDRIPciInit(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + ATIScreenInfo(pScreenPriv); + ATICardInfo(pScreenPriv); + unsigned char *mmio = atic->reg_base; + CARD32 chunk; + int ret; + + ATIDRIInitGARTValues(pScreen); + + ret = drmScatterGatherAlloc(atic->drmFd, atis->gartSize*1024*1024, + &atis->pciMemHandle); + if (ret < 0) { + ErrorF("[pci] Out of memory (%d)\n", ret); + return FALSE; + } + ErrorF("[pci] %d kB allocated with handle 0x%08lx\n", + atis->gartSize*1024, (long)atis->pciMemHandle); + + + if (!ATIDRIAddAndMap(atic->drmFd, atis->ringStart, atis->ringMapSize, + DRM_SCATTER_GATHER, DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL, + &atis->ringHandle, (drmAddressPtr)&atis->ring, "ring")) + return FALSE; + + if (!ATIDRIAddAndMap(atic->drmFd, atis->ringReadOffset, + atis->ringReadMapSize, DRM_SCATTER_GATHER, + DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL, + &atis->ringReadPtrHandle, (drmAddressPtr)&atis->ringReadPtr, + "ring read ptr")) + return FALSE; + + if (!ATIDRIAddAndMap(atic->drmFd, atis->bufStart, atis->bufMapSize, + DRM_SCATTER_GATHER, 0, &atis->bufHandle, (drmAddressPtr)&atis->buf, + "vertex/indirect buffers")) + return FALSE; + + if (!ATIDRIAddAndMap(atic->drmFd, atis->gartTexStart, + atis->gartTexMapSize, DRM_SCATTER_GATHER, 0, &atis->gartTexHandle, + (drmAddressPtr)&atis->gartTex, "PCI texture map")) + return FALSE; + + if (!atic->is_radeon) { + /* Force PCI GART mode */ + chunk = MMIO_IN32(mmio, R128_REG_BM_CHUNK_0_VAL); + chunk |= (R128_BM_PTR_FORCE_TO_PCI | + R128_BM_PM4_RD_FORCE_TO_PCI | R128_BM_GLOBAL_FORCE_TO_PCI); + MMIO_OUT32(mmio, R128_REG_BM_CHUNK_0_VAL, chunk); + MMIO_OUT32(mmio, R128_REG_PCI_GART_PAGE, 0); /* Ensure PCI GART is used */ + } + return TRUE; +} + + +/* Initialize the kernel data structures. */ +static int +R128DRIKernelInit(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + ATIScreenInfo(pScreenPriv); + ATICardInfo(pScreenPriv); + drmR128Init drmInfo; + + memset(&drmInfo, 0, sizeof(drmR128Init) ); + + drmInfo.func = DRM_R128_INIT_CCE; + drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); + drmInfo.is_pci = !atis->IsAGP; + drmInfo.cce_mode = atis->CCEMode; + drmInfo.cce_secure = TRUE; + drmInfo.ring_size = atis->ringSize*1024*1024; + drmInfo.usec_timeout = atis->DMAusecTimeout; + + drmInfo.fb_bpp = pScreenPriv->screen->fb[0].depth; + drmInfo.depth_bpp = pScreenPriv->screen->fb[0].depth; + + /* XXX: pitches are in pixels on r128. */ + drmInfo.front_offset = atis->frontOffset; + drmInfo.front_pitch = atis->frontPitch; + + drmInfo.back_offset = atis->backOffset; + drmInfo.back_pitch = atis->backPitch; + + drmInfo.depth_offset = atis->depthOffset; + drmInfo.depth_pitch = atis->depthPitch; + drmInfo.span_offset = atis->spanOffset; + + drmInfo.fb_offset = atis->fbHandle; + drmInfo.mmio_offset = atis->registerHandle; + drmInfo.ring_offset = atis->ringHandle; + drmInfo.ring_rptr_offset = atis->ringReadPtrHandle; + drmInfo.buffers_offset = atis->bufHandle; + drmInfo.agp_textures_offset = atis->gartTexHandle; + + if (drmCommandWrite(atic->drmFd, DRM_R128_INIT, &drmInfo, + sizeof(drmR128Init)) < 0) + return FALSE; + + return TRUE; +} + +/* Initialize the kernel data structures */ +static int +RadeonDRIKernelInit(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + ATIScreenInfo(pScreenPriv); + ATICardInfo(pScreenPriv); + drmRadeonInit drmInfo; + + memset(&drmInfo, 0, sizeof(drmRadeonInit)); + + if (atic->is_r200) + drmInfo.func = DRM_RADEON_INIT_R200_CP; + else + drmInfo.func = DRM_RADEON_INIT_CP; + + drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); + drmInfo.is_pci = !atis->IsAGP; + drmInfo.cp_mode = atis->CPMode; + drmInfo.gart_size = atis->gartSize*1024*1024; + drmInfo.ring_size = atis->ringSize*1024*1024; + drmInfo.usec_timeout = atis->DMAusecTimeout; + + drmInfo.fb_bpp = pScreenPriv->screen->fb[0].depth; + drmInfo.depth_bpp = pScreenPriv->screen->fb[0].depth; + + drmInfo.front_offset = atis->frontOffset; + drmInfo.front_pitch = atis->frontPitch; + drmInfo.back_offset = atis->backOffset; + drmInfo.back_pitch = atis->backPitch; + drmInfo.depth_offset = atis->depthOffset; + drmInfo.depth_pitch = atis->depthPitch; + + drmInfo.fb_offset = atis->fbHandle; + drmInfo.mmio_offset = atis->registerHandle; + drmInfo.ring_offset = atis->ringHandle; + drmInfo.ring_rptr_offset = atis->ringReadPtrHandle; + drmInfo.buffers_offset = atis->bufHandle; + drmInfo.gart_textures_offset = atis->gartTexHandle; + + if (drmCommandWrite(atic->drmFd, DRM_RADEON_CP_INIT, + &drmInfo, sizeof(drmRadeonInit)) < 0) + return FALSE; + + return TRUE; +} + +/* Add a map for the vertex buffers that will be accessed by any + DRI-based clients. */ +static Bool +ATIDRIBufInit(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + ATIScreenInfo(pScreenPriv); + ATICardInfo(pScreenPriv); + int type, size; + + if (atic->is_radeon) + size = RADEON_BUFFER_SIZE; + else + size = R128_BUFFER_SIZE; + + if (atis->IsAGP) + type = DRM_AGP_BUFFER; + else + type = DRM_SG_BUFFER; + + /* Initialize vertex buffers */ + atis->bufNumBufs = drmAddBufs(atic->drmFd, atis->bufMapSize / size, + size, type, atis->bufStart); + + if (atis->bufNumBufs <= 0) { + ErrorF("[drm] Could not create vertex/indirect buffers list\n"); + return FALSE; + } + ErrorF("[drm] Added %d %d byte vertex/indirect buffers\n", + atis->bufNumBufs, size); + + atis->buffers = drmMapBufs(atic->drmFd); + if (atis->buffers == NULL) { + ErrorF("[drm] Failed to map vertex/indirect buffers list\n"); + return FALSE; + } + ErrorF("[drm] Mapped %d vertex/indirect buffers\n", + atis->buffers->count); + + return TRUE; +} + +static int +ATIDRIIrqInit(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + ATIScreenInfo(pScreenPriv); + ATICardInfo(pScreenPriv); + + if (atis->irqEnabled) + return FALSE; + + atis->irqEnabled = drmCtlInstHandler(atic->drmFd, 0); + + if (!atis->irqEnabled) + return FALSE; + + return TRUE; +} + +static void ATIDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, + DRIContextType oldContextType, void *oldContext, + DRIContextType newContextType, void *newContext) +{ + KdScreenPriv(pScreen); + ATIScreenInfo(pScreenPriv); + + if ((syncType==DRI_3D_SYNC) && (oldContextType==DRI_2D_CONTEXT) && + (newContextType==DRI_2D_CONTEXT)) { + /* Entering from Wakeup */ + /* XXX: XFree86 sets NeedToSync */ + + } + if ((syncType==DRI_2D_SYNC) && (oldContextType==DRI_NO_CONTEXT) && + (newContextType==DRI_2D_CONTEXT)) { + /* Exiting from Block Handler */ + if (atis->using_dma) + ATIDMAFlushIndirect(1); + } +} + +/* 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 +ATIDRIScreenInit(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + ATIScreenInfo(pScreenPriv); + ATICardInfo(pScreenPriv); + void *scratch_ptr; + int scratch_int; + DRIInfoPtr pDRIInfo; + int devSareaSize; + drmSetVersion sv; + + /* XXX: Disable DRI clients for unsupported depths */ + + if (atic->is_radeon) { + atis->CPMode = RADEON_CSQ_PRIBM_INDBM; + } + else { + atis->CCEMode = R128_PM4_64BM_64VCBM_64INDBM; + atis->CCEFifoSize = 64; + } + + atis->IsAGP = FALSE; /* XXX */ + atis->agpMode = 1; + atis->gartSize = 8; + atis->ringSize = 1; + atis->bufSize = 2; + atis->gartTexSize = 1; + atis->DMAusecTimeout = 10000; + + atis->frontOffset = 0; + atis->frontPitch = pScreenPriv->screen->fb[0].byteStride; + atis->backOffset = 0; /* XXX */ + atis->backPitch = pScreenPriv->screen->fb[0].byteStride; + atis->depthOffset = 0; /* XXX */ + atis->depthPitch = 0; /* XXX */ + atis->spanOffset = 0; /* XXX */ + + if (atic->drmFd < 0) + return FALSE; + + sv.drm_di_major = -1; + sv.drm_dd_major = -1; + drmSetInterfaceVersion(atic->drmFd, &sv); + if (atic->is_radeon) { + if (sv.drm_dd_major != 1 || sv.drm_dd_minor < 6) { + ErrorF("[dri] radeon kernel module version is %d.%d " + "but version 1.6 or greater is needed.\n", + sv.drm_dd_major, sv.drm_dd_minor); + return FALSE; + } + } else { + if (sv.drm_dd_major != 2 || sv.drm_dd_minor < 2) { + ErrorF("[dri] r128 kernel module version is %d.%d " + "but version 2.2 or greater is needed.\n", + sv.drm_dd_major, sv.drm_dd_minor); + return FALSE; + } + } + + /* Create the DRI data structure, and fill it in before calling the + * DRIScreenInit(). + */ + pDRIInfo = DRICreateInfoRec(); + if (!pDRIInfo) + return FALSE; + + atis->pDRIInfo = pDRIInfo; + pDRIInfo->busIdString = atic->busid; + if (atic->is_radeon) { + pDRIInfo->drmDriverName = "radeon"; + if (atic->is_r200) + pDRIInfo->clientDriverName = "radeon"; + else + pDRIInfo->clientDriverName = "r200"; + } else { + pDRIInfo->drmDriverName = "r128"; + pDRIInfo->clientDriverName = "r128"; + } + pDRIInfo->ddxDriverMajorVersion = 4; + pDRIInfo->ddxDriverMinorVersion = 0; + pDRIInfo->ddxDriverPatchVersion = 0; + pDRIInfo->frameBufferPhysicalAddress = + (unsigned long)pScreenPriv->screen->memory_base; + pDRIInfo->frameBufferSize = pScreenPriv->screen->memory_size; + pDRIInfo->frameBufferStride = pScreenPriv->screen->fb[0].byteStride; + pDRIInfo->ddxDrawableTableEntry = SAREA_MAX_DRAWABLES; + pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; + + /* For now the mapping works by using a fixed size defined + * in the SAREA header + */ + pDRIInfo->SAREASize = SAREA_MAX; + + if (atic->is_radeon) { + pDRIInfo->devPrivateSize = sizeof(R128DRIRec); + devSareaSize = sizeof(R128SAREAPriv); + } else { + pDRIInfo->devPrivateSize = sizeof(RADEONDRIRec); + devSareaSize = sizeof(RADEONSAREAPriv); + } + + if (sizeof(XF86DRISAREARec) + devSareaSize > SAREA_MAX) { + ErrorF("[dri] Data does not fit in SAREA. Disabling DRI.\n"); + return FALSE; + } + + pDRIInfo->devPrivate = xcalloc(pDRIInfo->devPrivateSize, 1); + if (pDRIInfo->devPrivate == NULL) { + DRIDestroyInfoRec(atis->pDRIInfo); + atis->pDRIInfo = NULL; + return FALSE; + } + + pDRIInfo->contextSize = sizeof(ATIDRIContextRec); + + pDRIInfo->SwapContext = ATIDRISwapContext; + /*pDRIInfo->InitBuffers = R128DRIInitBuffers;*/ /* XXX Appears unnecessary */ + /*pDRIInfo->MoveBuffers = R128DRIMoveBuffers;*/ /* XXX Badness */ + pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; + /*pDRIInfo->TransitionTo2d = R128DRITransitionTo2d; + pDRIInfo->TransitionTo3d = R128DRITransitionTo3d; + pDRIInfo->TransitionSingleToMulti3D = R128DRITransitionSingleToMulti3d; + pDRIInfo->TransitionMultiToSingle3D = R128DRITransitionMultiToSingle3d;*/ + + pDRIInfo->createDummyCtx = TRUE; + pDRIInfo->createDummyCtxPriv = FALSE; + + if (!DRIScreenInit(pScreen, pDRIInfo, &atic->drmFd)) { + ErrorF("[dri] DRIScreenInit failed. Disabling DRI.\n"); + xfree(pDRIInfo->devPrivate); + pDRIInfo->devPrivate = NULL; + DRIDestroyInfoRec(pDRIInfo); + pDRIInfo = NULL; + return FALSE; + } + + /* Add a map for the MMIO registers that will be accessed by any + * DRI-based clients. + */ + atis->registerSize = RADEON_REG_SIZE(atic); + if (drmAddMap(atic->drmFd, RADEON_REG_BASE(pScreenPriv->screen->card), + atis->registerSize, DRM_REGISTERS, DRM_READ_ONLY, + &atis->registerHandle) < 0) { + ATIDRICloseScreen(pScreen); + return FALSE; + } + ErrorF("[drm] register handle = 0x%08lx\n", atis->registerHandle); + + /* DRIScreenInit adds the frame buffer map, but we need it as well */ + DRIGetDeviceInfo(pScreen, &atis->fbHandle, &scratch_int, &scratch_int, + &scratch_int, &scratch_int, &scratch_ptr); + + /* Initialize AGP */ + if (atis->IsAGP && !ATIDRIAgpInit(pScreen)) { + atis->IsAGP = FALSE; + ErrorF("[agp] AGP failed to initialize; falling back to PCI mode.\n"); + ErrorF("[agp] Make sure your kernel's AGP support is loaded and functioning."); + } + + /* Initialize PCIGART */ + if (!atis->IsAGP && !ATIDRIPciInit(pScreen)) { + ATIDRICloseScreen(pScreen); + return FALSE; + } + +#ifdef GLXEXT + if (!R128InitVisualConfigs(pScreen)) { + ATIDRICloseScreen(pScreen); + return FALSE; + } + ErrorF("[dri] Visual configs initialized\n"); +#endif + + atis->serverContext = DRIGetContext(pScreen); + + return ATIDRIFinishScreenInit(pScreen); +} + +/* Finish initializing the device-dependent DRI state, and call + DRIFinishScreenInit() to complete the device-independent DRI + initialization. */ +static Bool +R128DRIFinishScreenInit(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + ATIScreenInfo(pScreenPriv); + R128SAREAPrivPtr pSAREAPriv; + R128DRIPtr pR128DRI; + + /* Initialize the kernel data structures */ + if (!R128DRIKernelInit(pScreen)) { + ATIDRICloseScreen(pScreen); + return FALSE; + } + + /* Initialize the vertex buffers list */ + if (!ATIDRIBufInit(pScreen)) { + ATIDRICloseScreen(pScreen); + return FALSE; + } + + /* Initialize IRQ */ + ATIDRIIrqInit(pScreen); + + /* Initialize and start the CCE if required */ + ATIDMAStart(pScreen); + + pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScreen); + memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); + + pR128DRI = (R128DRIPtr)atis->pDRIInfo->devPrivate; + + pR128DRI->deviceID = pScreenPriv->screen->card->attr.deviceID; + pR128DRI->width = pScreenPriv->screen->width; + pR128DRI->height = pScreenPriv->screen->height; + pR128DRI->depth = pScreenPriv->screen->fb[0].depth; + pR128DRI->bpp = pScreenPriv->screen->fb[0].bitsPerPixel; + + pR128DRI->IsPCI = !atis->IsAGP; + pR128DRI->AGPMode = atis->agpMode; + + pR128DRI->frontOffset = atis->frontOffset; + pR128DRI->frontPitch = atis->frontPitch; + pR128DRI->backOffset = atis->backOffset; + pR128DRI->backPitch = atis->backPitch; + pR128DRI->depthOffset = atis->depthOffset; + pR128DRI->depthPitch = atis->depthPitch; + pR128DRI->spanOffset = atis->spanOffset; + pR128DRI->textureOffset = atis->textureOffset; + pR128DRI->textureSize = atis->textureSize; + pR128DRI->log2TexGran = atis->log2TexGran; + + pR128DRI->registerHandle = atis->registerHandle; + pR128DRI->registerSize = atis->registerSize; + + pR128DRI->gartTexHandle = atis->gartTexHandle; + pR128DRI->gartTexMapSize = atis->gartTexMapSize; + pR128DRI->log2AGPTexGran = atis->log2GARTTexGran; + pR128DRI->gartTexOffset = atis->gartTexStart; + pR128DRI->sarea_priv_offset = sizeof(XF86DRISAREARec); + + return TRUE; +} + +/* Finish initializing the device-dependent DRI state, and call + * DRIFinishScreenInit() to complete the device-independent DRI + * initialization. + */ +static Bool +RadeonDRIFinishScreenInit(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + ATIScreenInfo(pScreenPriv); + ATICardInfo(pScreenPriv); + RADEONSAREAPrivPtr pSAREAPriv; + RADEONDRIPtr pRADEONDRI; + drmRadeonMemInitHeap drmHeap; + + /* Initialize the kernel data structures */ + if (!RadeonDRIKernelInit(pScreen)) { + ATIDRICloseScreen(pScreen); + return FALSE; + } + + /* Initialize the vertex buffers list */ + if (!ATIDRIBufInit(pScreen)) { + ATIDRICloseScreen(pScreen); + return FALSE; + } + + /* Initialize IRQ */ + ATIDRIIrqInit(pScreen); + + drmHeap.region = RADEON_MEM_REGION_GART; + drmHeap.start = 0; + drmHeap.size = atis->gartTexMapSize; + + if (drmCommandWrite(atic->drmFd, DRM_RADEON_INIT_HEAP, &drmHeap, + sizeof(drmHeap))) { + ErrorF("[drm] Failed to initialize GART heap manager\n"); + } + + ATIDMAStart(pScreen); + + /* Initialize the SAREA private data structure */ + pSAREAPriv = (RADEONSAREAPrivPtr)DRIGetSAREAPrivate(pScreen); + memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); + + pRADEONDRI = (RADEONDRIPtr)atis->pDRIInfo->devPrivate; + + pRADEONDRI->deviceID = pScreenPriv->screen->card->attr.deviceID; + pRADEONDRI->width = pScreenPriv->screen->width; + pRADEONDRI->height = pScreenPriv->screen->height; + pRADEONDRI->depth = pScreenPriv->screen->fb[0].depth; + pRADEONDRI->bpp = pScreenPriv->screen->fb[0].bitsPerPixel; + + pRADEONDRI->IsPCI = !atis->IsAGP; + pRADEONDRI->AGPMode = atis->agpMode; + + pRADEONDRI->frontOffset = atis->frontOffset; + pRADEONDRI->frontPitch = atis->frontPitch; + pRADEONDRI->backOffset = atis->backOffset; + pRADEONDRI->backPitch = atis->backPitch; + pRADEONDRI->depthOffset = atis->depthOffset; + pRADEONDRI->depthPitch = atis->depthPitch; + pRADEONDRI->textureOffset = atis->textureOffset; + pRADEONDRI->textureSize = atis->textureSize; + pRADEONDRI->log2TexGran = atis->log2TexGran; + + pRADEONDRI->registerHandle = atis->registerHandle; + pRADEONDRI->registerSize = atis->registerSize; + + pRADEONDRI->statusHandle = atis->ringReadPtrHandle; + pRADEONDRI->statusSize = atis->ringReadMapSize; + + pRADEONDRI->gartTexHandle = atis->gartTexHandle; + pRADEONDRI->gartTexMapSize = atis->gartTexMapSize; + pRADEONDRI->log2GARTTexGran = atis->log2GARTTexGran; + pRADEONDRI->gartTexOffset = atis->gartTexStart; + + pRADEONDRI->sarea_priv_offset = sizeof(XF86DRISAREARec); + + return TRUE; +} + +static Bool +ATIDRIFinishScreenInit(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + ATIScreenInfo(pScreenPriv); + ATICardInfo (pScreenPriv); + + atis->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; + + /* NOTE: DRIFinishScreenInit must be called before *DRIKernelInit + * because *DRIKernelInit requires that the hardware lock is held by + * the X server, and the first time the hardware lock is grabbed is + * in DRIFinishScreenInit. + */ + if (!DRIFinishScreenInit(pScreen)) { + ATIDRICloseScreen(pScreen); + return FALSE; + } + + if (atic->is_radeon) { + if (!RadeonDRIFinishScreenInit(pScreen)) { + ATIDRICloseScreen(pScreen); + return FALSE; + } + } else { + if (!R128DRIFinishScreenInit(pScreen)) { + ATIDRICloseScreen(pScreen); + return FALSE; + } + } + + XFree86DRIExtensionInit(); + + atis->using_dri = TRUE; + + return TRUE; +} + +/* The screen is being closed, so clean up any state and free any + resources used by the DRI. */ +void +ATIDRICloseScreen(ScreenPtr pScreen) +{ + KdScreenPriv (pScreen); + ATIScreenInfo (pScreenPriv); + ATICardInfo (pScreenPriv); + drmR128Init drmR128Info; + drmRadeonInit drmRadeonInfo; + + if (atis->indirectBuffer != NULL) { + ATIDMADispatchIndirect(1); + atis->indirectBuffer = NULL; + atis->indirectStart = 0; + } + ATIDMAStop(pScreen); + + if (atis->irqEnabled) { + drmCtlUninstHandler(atic->drmFd); + atis->irqEnabled = FALSE; + } + + /* De-allocate vertex buffers */ + if (atis->buffers) { + drmUnmapBufs(atis->buffers); + atis->buffers = NULL; + } + + /* De-allocate all kernel resources */ + if (atic->is_radeon) { + memset(&drmR128Info, 0, sizeof(drmR128Init)); + drmR128Info.func = DRM_R128_CLEANUP_CCE; + drmCommandWrite(atic->drmFd, DRM_R128_INIT, &drmR128Info, + sizeof(drmR128Init)); + } else { + memset(&drmRadeonInfo, 0, sizeof(drmRadeonInfo)); + drmRadeonInfo.func = DRM_RADEON_CLEANUP_CP; + drmCommandWrite(atic->drmFd, DRM_RADEON_CP_INIT, &drmRadeonInfo, + sizeof(drmR128Init)); + } + + /* De-allocate all AGP resources */ + if (atis->gartTex) { + drmUnmap(atis->gartTex, atis->gartTexMapSize); + atis->gartTex = NULL; + } + if (atis->buf) { + drmUnmap(atis->buf, atis->bufMapSize); + atis->buf = NULL; + } + if (atis->ringReadPtr) { + drmUnmap(atis->ringReadPtr, atis->ringReadMapSize); + atis->ringReadPtr = NULL; + } + if (atis->ring) { + drmUnmap(atis->ring, atis->ringMapSize); + atis->ring = NULL; + } + if (atis->agpMemHandle != DRM_AGP_NO_HANDLE) { + drmAgpUnbind(atic->drmFd, atis->agpMemHandle); + drmAgpFree(atic->drmFd, atis->agpMemHandle); + atis->agpMemHandle = DRM_AGP_NO_HANDLE; + drmAgpRelease(atic->drmFd); + } + if (atis->pciMemHandle) { + drmScatterGatherFree(atic->drmFd, atis->pciMemHandle); + atis->pciMemHandle = 0; + } + + /* De-allocate all DRI resources */ + DRICloseScreen(pScreen); + + /* De-allocate all DRI data structures */ + if (atis->pDRIInfo) { + if (atis->pDRIInfo->devPrivate) { + xfree(atis->pDRIInfo->devPrivate); + atis->pDRIInfo->devPrivate = NULL; + } + DRIDestroyInfoRec(atis->pDRIInfo); + atis->pDRIInfo = NULL; + } + atis->using_dri = FALSE; +#ifdef GLXEXT + if (atis->pVisualConfigs) { + xfree(atis->pVisualConfigs); + atis->pVisualConfigs = NULL; + } + if (atis->pVisualConfigsPriv) { + xfree(atis->pVisualConfigsPriv); + atis->pVisualConfigsPriv = NULL; + } +#endif /* GLXEXT */ + atic->drmFd = -1; +} diff --git a/hw/kdrive/ati/ati_dri.h b/hw/kdrive/ati/ati_dri.h new file mode 100644 index 000000000..2e2b9501b --- /dev/null +++ b/hw/kdrive/ati/ati_dri.h @@ -0,0 +1,100 @@ +/* + * $Id$ + * + * Copyright © 2003 Eric Anholt + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Eric Anholt not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Eric Anholt makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ERIC ANHOLT 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. + */ +/* $Header$ */ + +#ifndef _ATI_DRI_H_ +#define _ATI_DRI_H_ + +typedef struct { + /* 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 IsPCI; /* Current card is a PCI card */ + int AGPMode; + + int frontOffset; /* Start of front buffer */ + int frontPitch; + int backOffset; /* Start of shared back buffer */ + int backPitch; + int depthOffset; /* Start of shared depth buffer */ + int depthPitch; + int spanOffset; /* Start of scratch spanline */ + int textureOffset; /* Start of texture data in frame buffer */ + int textureSize; + int log2TexGran; + + /* MMIO register data */ + drmHandle registerHandle; + drmSize registerSize; + + /* CCE AGP Texture data */ + drmHandle gartTexHandle; + drmSize gartTexMapSize; + int log2AGPTexGran; + int gartTexOffset; + unsigned int sarea_priv_offset; +} R128DRIRec, *R128DRIPtr; + +typedef struct { + /* 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 IsPCI; /* Current card is a PCI card */ + int AGPMode; + + int frontOffset; /* Start of front buffer */ + int frontPitch; + int backOffset; /* Start of shared back buffer */ + int backPitch; + int depthOffset; /* Start of shared depth buffer */ + int depthPitch; + int textureOffset; /* Start of texture data in frame buffer */ + int textureSize; + int log2TexGran; + + /* MMIO register data */ + drmHandle registerHandle; + drmSize registerSize; + + /* CP in-memory status information */ + drmHandle statusHandle; + drmSize statusSize; + + /* CP GART Texture data */ + drmHandle gartTexHandle; + drmSize gartTexMapSize; + int log2GARTTexGran; + int gartTexOffset; + unsigned int sarea_priv_offset; +} RADEONDRIRec, *RADEONDRIPtr; + +#endif /* _ATI_DRI_H_ */ diff --git a/hw/kdrive/ati/ati_dripriv.h b/hw/kdrive/ati/ati_dripriv.h new file mode 100644 index 000000000..1343f07f5 --- /dev/null +++ b/hw/kdrive/ati/ati_dripriv.h @@ -0,0 +1,58 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dripriv.h,v 1.3 2000/11/18 19:37:11 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, + * Precision Insight, Inc., Cedar Park, Texas, and + * VA Linux Systems Inc., Fremont, California. + * + * 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, 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 + * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, PRECISION INSIGHT, VA LINUX + * SYSTEMS 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@valinux.com> + * Kevin E. Martin <martin@valinux.com> + * + */ + +#ifndef _ATI_DRIPRIV_H_ +#define _ATI_DRIPRIV_H_ + +#ifdef GLXEXT +#include "GL/glxint.h" + +extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, + void **configprivs); +#endif + +typedef struct { + /* Nothing here yet */ + int dummy; +} ATIConfigPrivRec, *ATIConfigPrivPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} ATIDRIContextRec, *ATIDRIContextPtr; + +#endif diff --git a/hw/kdrive/ati/ati_reg.h b/hw/kdrive/ati/ati_reg.h index ac5221fe4..51d3c6739 100644 --- a/hw/kdrive/ati/ati_reg.h +++ b/hw/kdrive/ati/ati_reg.h @@ -24,29 +24,47 @@ /* $Header$ */ /* The Radeon register definitions are almost all the same for r128 */ +#define RADEON_REG_BUS_CNTL 0x0030 +# define RADEON_BUS_MASTER_DIS (1 << 6) +#define RADEON_GEN_INT_CNTL 0x0040 +#define RADEON_REG_AGP_BASE 0x0170 +#define RADEON_REG_AGP_CNTL 0x0174 +# define RADEON_AGP_APER_SIZE_256MB (0x00 << 0) +# define RADEON_AGP_APER_SIZE_128MB (0x20 << 0) +# define RADEON_AGP_APER_SIZE_64MB (0x30 << 0) +# define RADEON_AGP_APER_SIZE_32MB (0x38 << 0) +# define RADEON_AGP_APER_SIZE_16MB (0x3c << 0) +# define RADEON_AGP_APER_SIZE_8MB (0x3e << 0) +# define RADEON_AGP_APER_SIZE_4MB (0x3f << 0) +# define RADEON_AGP_APER_SIZE_MASK (0x3f << 0) #define RADEON_REG_RBBM_STATUS 0x0e40 # define RADEON_RBBM_FIFOCNT_MASK 0x007f # define RADEON_RBBM_ACTIVE (1 << 31) +#define RADEON_REG_CP_CSQ_CNTL 0x0740 +# define RADEON_CSQ_PRIBM_INDBM (4 << 28) #define RADEON_REG_SRC_PITCH_OFFSET 0x1428 #define RADEON_REG_DST_PITCH_OFFSET 0x142c #define RADEON_REG_SRC_Y_X 0x1434 #define RADEON_REG_DST_Y_X 0x1438 #define RADEON_REG_DST_HEIGHT_WIDTH 0x143c #define RADEON_REG_DP_GUI_MASTER_CNTL 0x146c -#define RADEON_REG_DP_BRUSH_FRGD_CLR 0x147c # define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) # define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) # define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4) # define RADEON_GMC_BRUSH_NONE (15 << 4) # define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12) # define RADEON_DP_SRC_SOURCE_MEMORY (2 << 24) +# define RADEON_GMC_3D_FCN_EN (1 << 27) # define RADEON_GMC_CLR_CMP_CNTL_DIS (1 << 28) # define RADEON_GMC_AUX_CLIP_DIS (1 << 29) +#define RADEON_REG_DP_BRUSH_FRGD_CLR 0x147c +#define RADEON_REG_DST_WIDTH_HEIGHT 0x1598 +#define RADEON_REG_CLR_CMP_CNTL 0x15c0 +#define RADEON_REG_AUX_SC_CNTL 0x1660 #define RADEON_REG_DP_CNTL 0x16c0 # define RADEON_DST_X_LEFT_TO_RIGHT (1 << 0) # define RADEON_DST_Y_TOP_TO_BOTTOM (1 << 1) -#define RADEON_REG_DST_WIDTH_HEIGHT 0x1598 -#define RADEON_REG_AUX_SC_CNTL 0x1660 +#define RADEON_REG_DP_MIX 0x16c8 #define RADEON_REG_DP_WRITE_MASK 0x16cc #define RADEON_REG_DEFAULT_OFFSET 0x16e0 #define RADEON_REG_DEFAULT_PITCH 0x16e4 @@ -61,7 +79,121 @@ # define RADEON_RB2D_DC_FLUSH_ALL 0xf # define RADEON_RB2D_DC_BUSY (1 << 31) +#define RADEON_CP_PACKET0 0x00000000 +#define RADEON_CP_PACKET1 0x40000000 +#define RADEON_CP_PACKET2 0x80000000 + #define R128_REG_PC_NGUI_CTLSTAT 0x0184 # define R128_PC_BUSY (1 << 31) +#define R128_REG_PCI_GART_PAGE 0x017c +#define R128_REG_PC_NGUI_CTLSTAT 0x0184 +#define R128_REG_BM_CHUNK_0_VAL 0x0a18 +# define R128_BM_PTR_FORCE_TO_PCI (1 << 21) +# define R128_BM_PM4_RD_FORCE_TO_PCI (1 << 22) +# define R128_BM_GLOBAL_FORCE_TO_PCI (1 << 23) #define R128_REG_GUI_STAT 0x1740 # define R128_GUI_ACTIVE (1 << 31) + +#define R128_REG_TEX_CNTL 0x1800 +#define R128_REG_SCALE_SRC_HEIGHT_WIDTH 0x1994 +#define R128_REG_SCALE_OFFSET_0 0x1998 +#define R128_REG_SCALE_PITCH 0x199c +#define R128_REG_SCALE_X_INC 0x19a0 +#define R128_REG_SCALE_Y_INC 0x19a4 +#define R128_REG_SCALE_HACC 0x19a8 +#define R128_REG_SCALE_VACC 0x19ac +#define R128_REG_SCALE_DST_X_Y 0x19b0 +#define R128_REG_SCALE_DST_HEIGHT_WIDTH 0x19b4 + +#define R128_REG_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_REG_SCALE_3D_DATATYPE 0x1a20 + +#define R128_REG_TEX_CNTL_C 0x1c9c +# define R128_TEX_ALPHA_EN (1 << 9) +# define R128_TEX_CACHE_FLUSH (1 << 23) + +#define R128_REG_PRIM_TEX_CNTL_C 0x1cb0 +#define R128_REG_PRIM_TEXTURE_COMBINE_CNTL_C 0x1cb4 + +#define R128_DATATYPE_C8 2 +#define R128_DATATYPE_ARGB_1555 3 +#define R128_DATATYPE_RGB_565 4 +#define R128_DATATYPE_ARGB_8888 6 +#define R128_DATATYPE_RGB_332 7 +#define R128_DATATYPE_Y8 8 +#define R128_DATATYPE_RGB_8 9 +#define R128_DATATYPE_VYUY_422 11 +#define R128_DATATYPE_YVYU_422 12 +#define R128_DATATYPE_AYUV_444 14 +#define R128_DATATYPE_ARGB_4444 15 + +#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) diff --git a/hw/kdrive/ati/ati_sarea.h b/hw/kdrive/ati/ati_sarea.h new file mode 100644 index 000000000..67da24aca --- /dev/null +++ b/hw/kdrive/ati/ati_sarea.h @@ -0,0 +1,42 @@ + +/* + * $Id$ + * + * Copyright © 2003 Eric Anholt + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Eric Anholt not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Eric Anholt makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ERIC ANHOLT 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. + */ +/* $Header$ */ + +#ifndef _ATI_SAREA_H_ +#define _ATI_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 ATI_CARD_HEAP 0 +#define ATI_GART_HEAP 1 +#define ATI_NR_TEX_HEAPS 2 +#define ATI_NR_TEX_REGIONS 64 +#define ATI_LOG_TEX_GRANULARITY 16 + +#include "r128_sarea.h" +#include "radeon_sarea.h" + +#endif /* _ATI_SAREA_H_ */ diff --git a/hw/kdrive/ati/ati_stub.c b/hw/kdrive/ati/ati_stub.c index 2cb9e0092..0162362bf 100644 --- a/hw/kdrive/ati/ati_stub.c +++ b/hw/kdrive/ati/ati_stub.c @@ -29,30 +29,17 @@ #include "ati.h" #include "klinux.h" -extern struct pci_id_list radeon_id_list[]; -extern struct pci_id_list r128_id_list[]; +extern struct pci_id_entry ati_pci_ids[]; void InitCard(char *name) { + struct pci_id_entry *id; KdCardAttr attr; - int i, j; - for (i = 0; radeon_id_list[i].name != NULL; i++) { - CARD16 vendor = radeon_id_list[i].vendor; - CARD16 device = radeon_id_list[i].device; - - j = 0; - while (LinuxFindPci(vendor, device, j++, &attr)) - KdCardInfoAdd(&ATIFuncs, &attr, 0); - } - - for (i = 0; r128_id_list[i].name != NULL; i++) { - CARD16 vendor = r128_id_list[i].vendor; - CARD16 device = r128_id_list[i].device; - - j = 0; - while (LinuxFindPci(vendor, device, j++, &attr)) + for (id = ati_pci_ids; id->name != NULL; id++) { + int j = 0; + while (LinuxFindPci(id->vendor, id->device, j++, &attr)) KdCardInfoAdd(&ATIFuncs, &attr, 0); } } diff --git a/hw/kdrive/ati/r128_blendtmp.h b/hw/kdrive/ati/r128_blendtmp.h new file mode 100644 index 000000000..57eeb21eb --- /dev/null +++ b/hw/kdrive/ati/r128_blendtmp.h @@ -0,0 +1,125 @@ +/* + * $Id$ + * + * Copyright © 2003 Eric Anholt, Anders Carlsson + * + * 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 Eric Anholt not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Eric Anholt makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ERIC ANHOLT 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. + */ +/* $Header$ */ + +#ifdef USE_DMA +#define TAG(x) x##DMA +#define LOCALS RING_LOCALS; \ + (void)atic +#define BEGIN(x) BEGIN_RING(x * 2) +#define OUT_REG(reg, val) OUT_RING_REG(reg, val) +#define END() ADVANCE_RING() +#else +#define TAG(x) x##MMIO +#define LOCALS char *mmio = atic->reg_base +#define BEGIN(x) ATIWaitAvailMMIO(x) +#define OUT_REG(reg, val) MMIO_OUT32(mmio, (reg), (val)) +#define END() +#endif + +static Bool +TAG(R128PrepareBlend)(int op, PicturePtr pSrcPicture, PicturePtr pDstPicture, + PixmapPtr pSrc, PixmapPtr pDst) +{ + KdScreenPriv(pDst->drawable.pScreen); + ATIScreenInfo(pScreenPriv); + ATICardInfo(pScreenPriv); + CARD32 dstDatatype, srcDatatype; + LOCALS; + + accel_atis = atis; + + if (!TAG(ATISetup)(pDst, pSrc)) + return FALSE; + + src_bpp = pSrc->drawable.bitsPerPixel; + + if (op >= sizeof(R128BlendOp)/sizeof(R128BlendOp[0])) + ATI_FALLBACK(("Unsupported op 0x%x\n", op)); + if (pSrcPicture->repeat) + ATI_FALLBACK(("repeat unsupported\n")); + if (pSrcPicture->transform != NULL) + ATI_FALLBACK(("transform unsupported\n")); + if (!R128GetDatatypePict(pDstPicture->format, &dstDatatype)) + ATI_FALLBACK(("Unsupported dest format 0x%x\n", + pDstPicture->format)); + if (!R128GetDatatypePict(pSrcPicture->format, &srcDatatype)) + ATI_FALLBACK(("Unsupported src format 0x%x\n", + pSrcPicture->format)); + + BEGIN(11); + OUT_REG(RADEON_REG_DP_GUI_MASTER_CNTL, + (dstDatatype << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_CLR_CMP_CNTL_DIS | + RADEON_GMC_AUX_CLIP_DIS | + (ATIBltRop[3] << 16) | + RADEON_GMC_3D_FCN_EN); + OUT_REG(R128_REG_TEX_CNTL_C, R128_TEX_ALPHA_EN | R128_TEX_CACHE_FLUSH); + OUT_REG(R128_REG_PRIM_TEXTURE_COMBINE_CNTL_C, 0); + OUT_REG(R128_REG_SCALE_3D_CNTL, + R128_SCALE_3D_SCALE | + R128BlendOp[op] | + R128_TEX_MAP_ALPHA_IN_TEXTURE); + OUT_REG(R128_REG_SCALE_3D_DATATYPE, srcDatatype); + OUT_REG(R128_REG_SCALE_PITCH, src_pitch / src_bpp); + /* 4.16 fixed point scaling factor? */ + OUT_REG(R128_REG_SCALE_X_INC, 65536); + OUT_REG(R128_REG_SCALE_Y_INC, 65536); + OUT_REG(R128_REG_SCALE_HACC, 0x00000000); + OUT_REG(R128_REG_SCALE_VACC, 0x00000000); + OUT_REG(RADEON_REG_DP_CNTL, + RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM ); + END(); + + return TRUE; +} + +static void +TAG(R128Blend)(int srcX, int srcY, int dstX, int dstY, int width, int height) +{ + ATIScreenInfo *atis = accel_atis; + ATICardInfo *atic = atis->atic; + LOCALS; + + BEGIN(4); + OUT_REG(R128_REG_SCALE_OFFSET_0, src_offset + srcY * src_pitch + srcX * + (src_bpp >> 3)); + OUT_REG(R128_REG_SCALE_SRC_HEIGHT_WIDTH, (height << 16) | width); + OUT_REG(R128_REG_SCALE_DST_X_Y, (dstX << 16) | dstY); + OUT_REG(R128_REG_SCALE_DST_HEIGHT_WIDTH, (height << 16) | width); + END(); +} + +static void +TAG(R128DoneBlend)(void) +{ +} + +#undef TAG +#undef LOCALS +#undef BEGIN +#undef OUT_REG +#undef END diff --git a/hw/kdrive/ati/r128_common.h b/hw/kdrive/ati/r128_common.h new file mode 100644 index 000000000..506f97c68 --- /dev/null +++ b/hw/kdrive/ati/r128_common.h @@ -0,0 +1,171 @@ +/* r128_common.h -- common header definitions for R128 2D/3D/DRM suite + * Created: Sun Apr 9 18:16:28 2000 by kevin@precisioninsight.com + * + * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2002 Tungsten Graphics, 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: + * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> + * + * Converted to common header format: + * Jens Owen <jens@tungstengraphics.com> + * + * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_common.h,v 1.2 2002/12/16 16:19:10 dawes Exp $ + * + */ + +#ifndef _R128_COMMON_H_ +#define _R128_COMMON_H_ + +#include "X11/Xmd.h" + +/* + * WARNING: If you change any of these defines, make sure to change + * the kernel include file as well (r128_drm.h) + */ + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_R128_INIT 0x00 +#define DRM_R128_CCE_START 0x01 +#define DRM_R128_CCE_STOP 0x02 +#define DRM_R128_CCE_RESET 0x03 +#define DRM_R128_CCE_IDLE 0x04 +#define DRM_R128_UNDEFINED1 0x05 +#define DRM_R128_RESET 0x06 +#define DRM_R128_SWAP 0x07 +#define DRM_R128_CLEAR 0x08 +#define DRM_R128_VERTEX 0x09 +#define DRM_R128_INDICES 0x0a +#define DRM_R128_BLIT 0x0b +#define DRM_R128_DEPTH 0x0c +#define DRM_R128_STIPPLE 0x0d +#define DRM_R128_UNDEFINED2 0x0e +#define DRM_R128_INDIRECT 0x0f +#define DRM_R128_FULLSCREEN 0x10 +#define DRM_R128_CLEAR2 0x11 +#define DRM_R128_GETPARAM 0x12 +#define DRM_R128_FLIP 0x13 + +#define DRM_R128_FRONT_BUFFER 0x1 +#define DRM_R128_BACK_BUFFER 0x2 +#define DRM_R128_DEPTH_BUFFER 0x4 + +typedef struct { + enum { + DRM_R128_INIT_CCE = 0x01, + DRM_R128_CLEANUP_CCE = 0x02 + } func; + unsigned long sarea_priv_offset; + int is_pci; + int cce_mode; + int cce_secure; /* FIXME: Deprecated, we should remove this */ + int ring_size; + int usec_timeout; + + unsigned int fb_bpp; + unsigned int front_offset, front_pitch; + unsigned int back_offset, back_pitch; + unsigned int depth_bpp; + unsigned int depth_offset, depth_pitch; + unsigned int span_offset; + + unsigned long fb_offset; + unsigned long mmio_offset; + unsigned long ring_offset; + unsigned long ring_rptr_offset; + unsigned long buffers_offset; + unsigned long agp_textures_offset; +} drmR128Init; + +typedef struct { + int flush; + int idle; +} drmR128CCEStop; + +typedef struct { + int idx; + int start; + int end; + int discard; +} drmR128Indirect; + +typedef struct { + int idx; + int pitch; + int offset; + int format; + unsigned short x, y; + unsigned short width, height; +} drmR128Blit; + +typedef struct { + enum { + DRM_R128_WRITE_SPAN = 0x01, + DRM_R128_WRITE_PIXELS = 0x02, + DRM_R128_READ_SPAN = 0x03, + DRM_R128_READ_PIXELS = 0x04 + } func; + int n; + int *x; + int *y; + unsigned int *buffer; + unsigned char *mask; +} drmR128Depth; + +typedef struct { + int prim; + int idx; /* Index of vertex buffer */ + int count; /* Number of vertices in buffer */ + int discard; /* Client finished with buffer? */ +} drmR128Vertex; + +typedef struct { + unsigned int *mask; +} drmR128Stipple; + +typedef struct { + unsigned int flags; + unsigned int clear_color; + unsigned int clear_depth; + unsigned int color_mask; + unsigned int depth_mask; +} drmR128Clear; + +typedef struct { + enum { + DRM_R128_INIT_FULLSCREEN = 0x01, + DRM_R128_CLEANUP_FULLSCREEN = 0x02 + } func; +} drmR128Fullscreen; + +typedef struct drm_r128_getparam { + int param; + int *value; +} drmR128GetParam; + +#define R128_PARAM_IRQ_NR 1 + +#endif diff --git a/hw/kdrive/ati/r128_sarea.h b/hw/kdrive/ati/r128_sarea.h new file mode 100644 index 000000000..b73797ae6 --- /dev/null +++ b/hw/kdrive/ati/r128_sarea.h @@ -0,0 +1,186 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h,v 1.7 2002/02/16 21:26:35 herrb Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, + * Precision Insight, Inc., Cedar Park, Texas, and + * VA Linux Systems Inc., Fremont, California. + * + * 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, 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 + * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, PRECISION INSIGHT, VA LINUX + * SYSTEMS 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 <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef _R128_SAREA_H_ +#define _R128_SAREA_H_ + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the kernel file (r128_drm.h) + */ +#ifndef __R128_SAREA_DEFINES__ +#define __R128_SAREA_DEFINES__ + +/* What needs to be changed for the current vertex buffer? + */ +#define R128_UPLOAD_CONTEXT 0x001 +#define R128_UPLOAD_SETUP 0x002 +#define R128_UPLOAD_TEX0 0x004 +#define R128_UPLOAD_TEX1 0x008 +#define R128_UPLOAD_TEX0IMAGES 0x010 +#define R128_UPLOAD_TEX1IMAGES 0x020 +#define R128_UPLOAD_CORE 0x040 +#define R128_UPLOAD_MASKS 0x080 +#define R128_UPLOAD_WINDOW 0x100 +#define R128_UPLOAD_CLIPRECTS 0x200 /* handled client-side */ +#define R128_REQUIRE_QUIESCENCE 0x400 +#define R128_UPLOAD_ALL 0x7ff + +#define R128_FRONT 0x1 +#define R128_BACK 0x2 +#define R128_DEPTH 0x4 + +/* Primitive types + */ +#define R128_POINTS 0x1 +#define R128_LINES 0x2 +#define R128_LINE_STRIP 0x3 +#define R128_TRIANGLES 0x4 +#define R128_TRIANGLE_FAN 0x5 +#define R128_TRIANGLE_STRIP 0x6 + +/* Vertex/indirect buffer size + */ +#define R128_BUFFER_SIZE 16384 + +/* Byte offsets for indirect buffer data + */ +#define R128_INDEX_PRIM_OFFSET 20 +#define R128_HOSTDATA_BLIT_OFFSET 32 + +/* Keep these small for testing + */ +#define R128_NR_SAREA_CLIPRECTS 12 + +#define R128_NR_CONTEXT_REGS 12 + +#define R128_MAX_TEXTURE_LEVELS 11 +#define R128_MAX_TEXTURE_UNITS 2 + +#endif /* __R128_SAREA_DEFINES__ */ + +typedef struct { + /* Context state - can be written in one large chunk */ + unsigned int dst_pitch_offset_c; + unsigned int dp_gui_master_cntl_c; + unsigned int sc_top_left_c; + unsigned int sc_bottom_right_c; + unsigned int z_offset_c; + unsigned int z_pitch_c; + unsigned int z_sten_cntl_c; + unsigned int tex_cntl_c; + unsigned int misc_3d_state_cntl_reg; + unsigned int texture_clr_cmp_clr_c; + unsigned int texture_clr_cmp_msk_c; + unsigned int fog_color_c; + + /* Texture state */ + unsigned int tex_size_pitch_c; + unsigned int constant_color_c; + + /* Setup state */ + unsigned int pm4_vc_fpu_setup; + unsigned int setup_cntl; + + /* Mask state */ + unsigned int dp_write_mask; + unsigned int sten_ref_mask_c; + unsigned int plane_3d_mask_c; + + /* Window state */ + unsigned int window_xy_offset; + + /* Core state */ + unsigned int scale_3d_cntl; +} r128_context_regs_t; + +/* Setup registers for each texture unit + */ +typedef struct { + unsigned int tex_cntl; + unsigned int tex_combine_cntl; + unsigned int tex_size_pitch; + unsigned int tex_offset[R128_MAX_TEXTURE_LEVELS]; + unsigned int tex_border_color; +} r128_texture_regs_t; + +typedef struct { + /* The channel for communication of state information to the kernel + * on firing a vertex buffer. + */ + r128_context_regs_t ContextState; + r128_texture_regs_t TexState[R128_MAX_TEXTURE_UNITS]; + unsigned int dirty; + unsigned int vertsize; + unsigned int vc_format; + +#ifdef XF86DRI + /* The current cliprects, or a subset thereof. + */ + XF86DRIClipRectRec boxes[R128_NR_SAREA_CLIPRECTS]; + unsigned int nbox; +#endif + + /* Counters for throttling of rendering clients. + */ + unsigned int last_frame; + unsigned int last_dispatch; + + /* 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 */ + drmTextureRegion texList[ATI_NR_TEX_HEAPS][ATI_NR_TEX_REGIONS+1]; + /* last time texture was uploaded */ + unsigned int texAge[ATI_NR_TEX_HEAPS]; + + int ctxOwner; /* last context to upload state */ + int pfAllowPageFlip; /* set by the 2d driver, read by the client */ + int pfCurrentPage; /* set by kernel, read by others */ +} R128SAREAPriv, *R128SAREAPrivPtr; + +#endif diff --git a/hw/kdrive/ati/radeon_common.h b/hw/kdrive/ati/radeon_common.h new file mode 100644 index 000000000..2539ba68f --- /dev/null +++ b/hw/kdrive/ati/radeon_common.h @@ -0,0 +1,461 @@ +/* radeon_common.h -- common header definitions for Radeon 2D/3D/DRM suite + * + * Copyright 2000 VA Linux Systems, Inc., Fremont, California. + * Copyright 2002 Tungsten Graphics, 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: + * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> + * + * Converted to common header format: + * Jens Owen <jens@tungstengraphics.com> + * + * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h,v 1.2 2003/04/07 01:22:09 martin Exp $ + * + */ + +#ifndef _RADEON_COMMON_H_ +#define _RADEON_COMMON_H_ + +#include <inttypes.h> + +/* WARNING: If you change any of these defines, make sure to change + * the kernel include file as well (radeon_drm.h) + */ + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_RADEON_CP_INIT 0x00 +#define DRM_RADEON_CP_START 0x01 +#define DRM_RADEON_CP_STOP 0x02 +#define DRM_RADEON_CP_RESET 0x03 +#define DRM_RADEON_CP_IDLE 0x04 +#define DRM_RADEON_RESET 0x05 +#define DRM_RADEON_FULLSCREEN 0x06 +#define DRM_RADEON_SWAP 0x07 +#define DRM_RADEON_CLEAR 0x08 +#define DRM_RADEON_VERTEX 0x09 +#define DRM_RADEON_INDICES 0x0a +#define DRM_RADEON_STIPPLE 0x0c +#define DRM_RADEON_INDIRECT 0x0d +#define DRM_RADEON_TEXTURE 0x0e +#define DRM_RADEON_VERTEX2 0x0f +#define DRM_RADEON_CMDBUF 0x10 +#define DRM_RADEON_GETPARAM 0x11 +#define DRM_RADEON_FLIP 0x12 +#define DRM_RADEON_ALLOC 0x13 +#define DRM_RADEON_FREE 0x14 +#define DRM_RADEON_INIT_HEAP 0x15 +#define DRM_RADEON_IRQ_EMIT 0x16 +#define DRM_RADEON_IRQ_WAIT 0x17 +#define DRM_RADEON_CP_RESUME 0x18 +#define DRM_RADEON_SETPARAM 0x19 +#define DRM_RADEON_MAX_DRM_COMMAND_INDEX 0x39 + + +#define RADEON_FRONT 0x1 +#define RADEON_BACK 0x2 +#define RADEON_DEPTH 0x4 +#define RADEON_STENCIL 0x8 + +#define RADEON_CLEAR_X1 0 +#define RADEON_CLEAR_Y1 1 +#define RADEON_CLEAR_X2 2 +#define RADEON_CLEAR_Y2 3 +#define RADEON_CLEAR_DEPTH 4 + + +typedef struct { + enum { + DRM_RADEON_INIT_CP = 0x01, + DRM_RADEON_CLEANUP_CP = 0x02, + DRM_RADEON_INIT_R200_CP = 0x03 + } func; + unsigned long sarea_priv_offset; + int is_pci; + int cp_mode; + int gart_size; + int ring_size; + int usec_timeout; + + unsigned int fb_bpp; + unsigned int front_offset, front_pitch; + unsigned int back_offset, back_pitch; + unsigned int depth_bpp; + unsigned int depth_offset, depth_pitch; + + unsigned long fb_offset; + unsigned long mmio_offset; + unsigned long ring_offset; + unsigned long ring_rptr_offset; + unsigned long buffers_offset; + unsigned long gart_textures_offset; +} drmRadeonInit; + +typedef struct { + int flush; + int idle; +} drmRadeonCPStop; + +typedef struct { + int idx; + int start; + int end; + int discard; +} drmRadeonIndirect; + +typedef union drmRadeonClearR { + float f[5]; + unsigned int ui[5]; +} drmRadeonClearRect; + +typedef struct drmRadeonClearT { + unsigned int flags; + unsigned int clear_color; + unsigned int clear_depth; + unsigned int color_mask; + unsigned int depth_mask; /* misnamed field: should be stencil */ + drmRadeonClearRect *depth_boxes; +} drmRadeonClearType; + +typedef struct drmRadeonFullscreenT { + enum { + RADEON_INIT_FULLSCREEN = 0x01, + RADEON_CLEANUP_FULLSCREEN = 0x02 + } func; +} drmRadeonFullscreenType; + +typedef struct { + unsigned int *mask; +} drmRadeonStipple; + +typedef struct { + unsigned int x; + unsigned int y; + unsigned int width; + unsigned int height; + const void *data; +} drmRadeonTexImage; + +typedef struct { + unsigned int offset; + int pitch; + int format; + int width; /* Texture image coordinates */ + int height; + drmRadeonTexImage *image; +} drmRadeonTexture; + + +#define RADEON_MAX_TEXTURE_UNITS 3 + +/* Layout matches drm_radeon_state_t in linux drm_radeon.h. + */ +typedef struct { + struct { + unsigned int pp_misc; /* 0x1c14 */ + unsigned int pp_fog_color; + unsigned int re_solid_color; + unsigned int rb3d_blendcntl; + unsigned int rb3d_depthoffset; + unsigned int rb3d_depthpitch; + unsigned int rb3d_zstencilcntl; + unsigned int pp_cntl; /* 0x1c38 */ + unsigned int rb3d_cntl; + unsigned int rb3d_coloroffset; + unsigned int re_width_height; + unsigned int rb3d_colorpitch; + } context; + struct { + unsigned int se_cntl; + } setup1; + struct { + unsigned int se_coord_fmt; /* 0x1c50 */ + } vertex; + struct { + unsigned int re_line_pattern; /* 0x1cd0 */ + unsigned int re_line_state; + unsigned int se_line_width; /* 0x1db8 */ + } line; + struct { + unsigned int pp_lum_matrix; /* 0x1d00 */ + unsigned int pp_rot_matrix_0; /* 0x1d58 */ + unsigned int pp_rot_matrix_1; + } bumpmap; + struct { + unsigned int rb3d_stencilrefmask; /* 0x1d7c */ + unsigned int rb3d_ropcntl; + unsigned int rb3d_planemask; + } mask; + struct { + unsigned int se_vport_xscale; /* 0x1d98 */ + unsigned int se_vport_xoffset; + unsigned int se_vport_yscale; + unsigned int se_vport_yoffset; + unsigned int se_vport_zscale; + unsigned int se_vport_zoffset; + } viewport; + struct { + unsigned int se_cntl_status; /* 0x2140 */ + } setup2; + struct { + unsigned int re_top_left; /*ignored*/ /* 0x26c0 */ + unsigned int re_misc; + } misc; + struct { + unsigned int pp_txfilter; + unsigned int pp_txformat; + unsigned int pp_txoffset; + unsigned int pp_txcblend; + unsigned int pp_txablend; + unsigned int pp_tfactor; + unsigned int pp_border_color; + } texture[RADEON_MAX_TEXTURE_UNITS]; + struct { + unsigned int se_zbias_factor; + unsigned int se_zbias_constant; + } zbias; + unsigned int dirty; +} drmRadeonState; + +/* 1.1 vertex ioctl. Used in compatibility modes. + */ +typedef struct { + int prim; + int idx; /* Index of vertex buffer */ + int count; /* Number of vertices in buffer */ + int discard; /* Client finished with buffer? */ +} drmRadeonVertex; + +typedef struct { + unsigned int start; + unsigned int finish; + unsigned int prim:8; + unsigned int stateidx:8; + unsigned int numverts:16; /* overloaded as offset/64 for elt prims */ + unsigned int vc_format; +} drmRadeonPrim; + +typedef struct { + int idx; /* Index of vertex buffer */ + int discard; /* Client finished with buffer? */ + int nr_states; + drmRadeonState *state; + int nr_prims; + drmRadeonPrim *prim; +} drmRadeonVertex2; + +#define RADEON_MAX_STATES 16 +#define RADEON_MAX_PRIMS 64 + +/* Command buffer. Replace with true dma stream? + */ +typedef struct { + int bufsz; + char *buf; + int nbox; + drmClipRect *boxes; +} drmRadeonCmdBuffer; + +/* New style per-packet identifiers for use in cmd_buffer ioctl with + * the RADEON_EMIT_PACKET command. Comments relate new packets to old + * state bits and the packet size: + */ +#define RADEON_EMIT_PP_MISC 0 /* context/7 */ +#define RADEON_EMIT_PP_CNTL 1 /* context/3 */ +#define RADEON_EMIT_RB3D_COLORPITCH 2 /* context/1 */ +#define RADEON_EMIT_RE_LINE_PATTERN 3 /* line/2 */ +#define RADEON_EMIT_SE_LINE_WIDTH 4 /* line/1 */ +#define RADEON_EMIT_PP_LUM_MATRIX 5 /* bumpmap/1 */ +#define RADEON_EMIT_PP_ROT_MATRIX_0 6 /* bumpmap/2 */ +#define RADEON_EMIT_RB3D_STENCILREFMASK 7 /* masks/3 */ +#define RADEON_EMIT_SE_VPORT_XSCALE 8 /* viewport/6 */ +#define RADEON_EMIT_SE_CNTL 9 /* setup/2 */ +#define RADEON_EMIT_SE_CNTL_STATUS 10 /* setup/1 */ +#define RADEON_EMIT_RE_MISC 11 /* misc/1 */ +#define RADEON_EMIT_PP_TXFILTER_0 12 /* tex0/6 */ +#define RADEON_EMIT_PP_BORDER_COLOR_0 13 /* tex0/1 */ +#define RADEON_EMIT_PP_TXFILTER_1 14 /* tex1/6 */ +#define RADEON_EMIT_PP_BORDER_COLOR_1 15 /* tex1/1 */ +#define RADEON_EMIT_PP_TXFILTER_2 16 /* tex2/6 */ +#define RADEON_EMIT_PP_BORDER_COLOR_2 17 /* tex2/1 */ +#define RADEON_EMIT_SE_ZBIAS_FACTOR 18 /* zbias/2 */ +#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT 19 /* tcl/11 */ +#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED 20 /* material/17 */ +#define R200_EMIT_PP_TXCBLEND_0 21 /* tex0/4 */ +#define R200_EMIT_PP_TXCBLEND_1 22 /* tex1/4 */ +#define R200_EMIT_PP_TXCBLEND_2 23 /* tex2/4 */ +#define R200_EMIT_PP_TXCBLEND_3 24 /* tex3/4 */ +#define R200_EMIT_PP_TXCBLEND_4 25 /* tex4/4 */ +#define R200_EMIT_PP_TXCBLEND_5 26 /* tex5/4 */ +#define R200_EMIT_PP_TXCBLEND_6 27 /* /4 */ +#define R200_EMIT_PP_TXCBLEND_7 28 /* /4 */ +#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0 29 /* tcl/6 */ +#define R200_EMIT_TFACTOR_0 30 /* tf/6 */ +#define R200_EMIT_VTX_FMT_0 31 /* vtx/4 */ +#define R200_EMIT_VAP_CTL 32 /* vap/1 */ +#define R200_EMIT_MATRIX_SELECT_0 33 /* msl/5 */ +#define R200_EMIT_TEX_PROC_CTL_2 34 /* tcg/5 */ +#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL 35 /* tcl/1 */ +#define R200_EMIT_PP_TXFILTER_0 36 /* tex0/6 */ +#define R200_EMIT_PP_TXFILTER_1 37 /* tex1/6 */ +#define R200_EMIT_PP_TXFILTER_2 38 /* tex2/6 */ +#define R200_EMIT_PP_TXFILTER_3 39 /* tex3/6 */ +#define R200_EMIT_PP_TXFILTER_4 40 /* tex4/6 */ +#define R200_EMIT_PP_TXFILTER_5 41 /* tex5/6 */ +#define R200_EMIT_PP_TXOFFSET_0 42 /* tex0/1 */ +#define R200_EMIT_PP_TXOFFSET_1 43 /* tex1/1 */ +#define R200_EMIT_PP_TXOFFSET_2 44 /* tex2/1 */ +#define R200_EMIT_PP_TXOFFSET_3 45 /* tex3/1 */ +#define R200_EMIT_PP_TXOFFSET_4 46 /* tex4/1 */ +#define R200_EMIT_PP_TXOFFSET_5 47 /* tex5/1 */ +#define R200_EMIT_VTE_CNTL 48 /* vte/1 */ +#define R200_EMIT_OUTPUT_VTX_COMP_SEL 49 /* vtx/1 */ +#define R200_EMIT_PP_TAM_DEBUG3 50 /* tam/1 */ +#define R200_EMIT_PP_CNTL_X 51 /* cst/1 */ +#define R200_EMIT_RB3D_DEPTHXY_OFFSET 52 /* cst/1 */ +#define R200_EMIT_RE_AUX_SCISSOR_CNTL 53 /* cst/1 */ +#define R200_EMIT_RE_SCISSOR_TL_0 54 /* cst/2 */ +#define R200_EMIT_RE_SCISSOR_TL_1 55 /* cst/2 */ +#define R200_EMIT_RE_SCISSOR_TL_2 56 /* cst/2 */ +#define R200_EMIT_SE_VAP_CNTL_STATUS 57 /* cst/1 */ +#define R200_EMIT_SE_VTX_STATE_CNTL 58 /* cst/1 */ +#define R200_EMIT_RE_POINTSIZE 59 /* cst/1 */ +#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 60 /* cst/4 */ +#define R200_EMIT_PP_CUBIC_FACES_0 61 +#define R200_EMIT_PP_CUBIC_OFFSETS_0 62 +#define R200_EMIT_PP_CUBIC_FACES_1 63 +#define R200_EMIT_PP_CUBIC_OFFSETS_1 64 +#define R200_EMIT_PP_CUBIC_FACES_2 65 +#define R200_EMIT_PP_CUBIC_OFFSETS_2 66 +#define R200_EMIT_PP_CUBIC_FACES_3 67 +#define R200_EMIT_PP_CUBIC_OFFSETS_3 68 +#define R200_EMIT_PP_CUBIC_FACES_4 69 +#define R200_EMIT_PP_CUBIC_OFFSETS_4 70 +#define R200_EMIT_PP_CUBIC_FACES_5 71 +#define R200_EMIT_PP_CUBIC_OFFSETS_5 72 +#define RADEON_EMIT_PP_TEX_SIZE_0 73 +#define RADEON_EMIT_PP_TEX_SIZE_1 74 +#define RADEON_EMIT_PP_TEX_SIZE_2 75 +#define RADEON_MAX_STATE_PACKETS 76 + + +/* Commands understood by cmd_buffer ioctl. More can be added but + * obviously these can't be removed or changed: + */ +#define RADEON_CMD_PACKET 1 /* emit one of the register packets above */ +#define RADEON_CMD_SCALARS 2 /* emit scalar data */ +#define RADEON_CMD_VECTORS 3 /* emit vector data */ +#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */ +#define RADEON_CMD_PACKET3 5 /* emit hw packet */ +#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */ +#define RADEON_CMD_SCALARS2 7 /* R200 stopgap */ +#define RADEON_CMD_WAIT 8 /* synchronization */ + +typedef union { + int i; + struct { + unsigned char cmd_type, pad0, pad1, pad2; + } header; + struct { + unsigned char cmd_type, packet_id, pad0, pad1; + } packet; + struct { + unsigned char cmd_type, offset, stride, count; + } scalars; + struct { + unsigned char cmd_type, offset, stride, count; + } vectors; + struct { + unsigned char cmd_type, buf_idx, pad0, pad1; + } dma; + struct { + unsigned char cmd_type, flags, pad0, pad1; + } wait; +} drmRadeonCmdHeader; + + +#define RADEON_WAIT_2D 0x1 +#define RADEON_WAIT_3D 0x2 + + +typedef struct drm_radeon_getparam { + int param; + int *value; +} drmRadeonGetParam; + +#define RADEON_PARAM_GART_BUFFER_OFFSET 1 +#define RADEON_PARAM_LAST_FRAME 2 +#define RADEON_PARAM_LAST_DISPATCH 3 +#define RADEON_PARAM_LAST_CLEAR 4 +#define RADEON_PARAM_IRQ_NR 5 +#define RADEON_PARAM_GART_BASE 6 + + +#define RADEON_MEM_REGION_GART 1 +#define RADEON_MEM_REGION_FB 2 + +typedef struct drm_radeon_mem_alloc { + int region; + int alignment; + int size; + int *region_offset; /* offset from start of fb or GART */ +} drmRadeonMemAlloc; + +typedef struct drm_radeon_mem_free { + int region; + int region_offset; +} drmRadeonMemFree; + +typedef struct drm_radeon_mem_init_heap { + int region; + int size; + int start; +} drmRadeonMemInitHeap; + +/* 1.6: Userspace can request & wait on irq's: + */ +typedef struct drm_radeon_irq_emit { + int *irq_seq; +} drmRadeonIrqEmit; + +typedef struct drm_radeon_irq_wait { + int irq_seq; +} drmRadeonIrqWait; + + +/* 1.10: Clients tell the DRM where they think the framebuffer is located in + * the card's address space, via a new generic ioctl to set parameters + */ + +typedef struct drm_radeon_set_param { + unsigned int param; + int64_t value; +} drmRadeonSetParam; + +#define RADEON_SETPARAM_FB_LOCATION 1 + + +#endif diff --git a/hw/kdrive/ati/radeon_sarea.h b/hw/kdrive/ati/radeon_sarea.h new file mode 100644 index 000000000..82a72ed19 --- /dev/null +++ b/hw/kdrive/ati/radeon_sarea.h @@ -0,0 +1,222 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h,v 1.5 2002/10/30 12:52:14 alanh Exp $ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario, + * VA Linux Systems Inc., Fremont, California. + * + * 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, 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 + * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS 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 <martin@xfree86.org> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef _RADEON_SAREA_H_ +#define _RADEON_SAREA_H_ + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the kernel file (radeon_drm.h) + */ +#ifndef __RADEON_SAREA_DEFINES__ +#define __RADEON_SAREA_DEFINES__ + +/* What needs to be changed for the current vertex buffer? */ +#define RADEON_UPLOAD_CONTEXT 0x00000001 +#define RADEON_UPLOAD_VERTFMT 0x00000002 +#define RADEON_UPLOAD_LINE 0x00000004 +#define RADEON_UPLOAD_BUMPMAP 0x00000008 +#define RADEON_UPLOAD_MASKS 0x00000010 +#define RADEON_UPLOAD_VIEWPORT 0x00000020 +#define RADEON_UPLOAD_SETUP 0x00000040 +#define RADEON_UPLOAD_TCL 0x00000080 +#define RADEON_UPLOAD_MISC 0x00000100 +#define RADEON_UPLOAD_TEX0 0x00000200 +#define RADEON_UPLOAD_TEX1 0x00000400 +#define RADEON_UPLOAD_TEX2 0x00000800 +#define RADEON_UPLOAD_TEX0IMAGES 0x00001000 +#define RADEON_UPLOAD_TEX1IMAGES 0x00002000 +#define RADEON_UPLOAD_TEX2IMAGES 0x00004000 +#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */ +#define RADEON_REQUIRE_QUIESCENCE 0x00010000 +#define RADEON_UPLOAD_ZBIAS 0x00020000 +#define RADEON_UPLOAD_ALL 0x0002ffff +#define RADEON_UPLOAD_CONTEXT_ALL 0x000201ff + +#define RADEON_FRONT 0x1 +#define RADEON_BACK 0x2 +#define RADEON_DEPTH 0x4 +#define RADEON_STENCIL 0x8 + +/* Primitive types */ +#define RADEON_POINTS 0x1 +#define RADEON_LINES 0x2 +#define RADEON_LINE_STRIP 0x3 +#define RADEON_TRIANGLES 0x4 +#define RADEON_TRIANGLE_FAN 0x5 +#define RADEON_TRIANGLE_STRIP 0x6 +#define RADEON_3VTX_POINTS 0x9 +#define RADEON_3VTX_LINES 0xa + +/* Vertex/indirect buffer size */ +#define RADEON_BUFFER_SIZE 65536 + +/* Byte offsets for indirect buffer data */ +#define RADEON_INDEX_PRIM_OFFSET 20 +#define RADEON_HOSTDATA_BLIT_OFFSET 32 + +#define RADEON_SCRATCH_REG_OFFSET 32 + +/* Keep these small for testing */ +#define RADEON_NR_SAREA_CLIPRECTS 12 + +#define RADEON_MAX_TEXTURE_LEVELS 12 +#define RADEON_MAX_TEXTURE_UNITS 3 + +/* Blits have strict offset rules. All blit offset must be aligned on + * a 1K-byte boundary. + */ +#define RADEON_OFFSET_SHIFT 10 +#define RADEON_OFFSET_ALIGN (1 << RADEON_OFFSET_SHIFT) +#define RADEON_OFFSET_MASK (RADEON_OFFSET_ALIGN - 1) + +#endif /* __RADEON_SAREA_DEFINES__ */ + +typedef struct { + unsigned int red; + unsigned int green; + unsigned int blue; + unsigned int alpha; +} radeon_color_regs_t; + +typedef struct { + /* Context state */ + unsigned int pp_misc; + unsigned int pp_fog_color; + unsigned int re_solid_color; + unsigned int rb3d_blendcntl; + unsigned int rb3d_depthoffset; + unsigned int rb3d_depthpitch; + unsigned int rb3d_zstencilcntl; + + unsigned int pp_cntl; + unsigned int rb3d_cntl; + unsigned int rb3d_coloroffset; + unsigned int re_width_height; + unsigned int rb3d_colorpitch; + unsigned int se_cntl; + + /* Vertex format state */ + unsigned int se_coord_fmt; + + /* Line state */ + unsigned int re_line_pattern; + unsigned int re_line_state; + + unsigned int se_line_width; + + /* Bumpmap state */ + unsigned int pp_lum_matrix; + + unsigned int pp_rot_matrix_0; + unsigned int pp_rot_matrix_1; + + /* Mask state */ + unsigned int rb3d_stencilrefmask; + unsigned int rb3d_ropcntl; + unsigned int rb3d_planemask; + + /* Viewport state */ + unsigned int se_vport_xscale; + unsigned int se_vport_xoffset; + unsigned int se_vport_yscale; + unsigned int se_vport_yoffset; + unsigned int se_vport_zscale; + unsigned int se_vport_zoffset; + + /* Setup state */ + unsigned int se_cntl_status; + + /* Misc state */ + unsigned int re_top_left; + unsigned int re_misc; +} radeon_context_regs_t; + +/* Setup registers for each texture unit */ +typedef struct { + unsigned int pp_txfilter; + unsigned int pp_txformat; + unsigned int pp_txoffset; + unsigned int pp_txcblend; + unsigned int pp_txablend; + unsigned int pp_tfactor; + unsigned int pp_border_color; +} radeon_texture_regs_t; + +typedef struct { + /* The channel for communication of state information to the kernel + * on firing a vertex buffer. + */ + radeon_context_regs_t ContextState; + radeon_texture_regs_t TexState[RADEON_MAX_TEXTURE_UNITS]; + unsigned int dirty; + unsigned int vertsize; + unsigned int vc_format; + + /* The current cliprects, or a subset thereof */ + XF86DRIClipRectRec boxes[RADEON_NR_SAREA_CLIPRECTS]; + unsigned int nbox; + + /* Counters for throttling of rendering clients */ + unsigned int last_frame; + unsigned int last_dispatch; + unsigned int last_clear; + + /* 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 */ + drmTextureRegion texList[ATI_NR_TEX_HEAPS][ATI_NR_TEX_REGIONS+1]; + /* last time texture was uploaded */ + unsigned int texAge[ATI_NR_TEX_HEAPS]; + + int ctxOwner; /* last context to upload state */ + int pfAllowPageFlip; /* set by the 2d driver, read by the client */ + int pfCurrentPage; /* set by kernel, read by others */ + int crtc2_base; /* for pageflipping with CloneMode */ +} RADEONSAREAPriv, *RADEONSAREAPrivPtr; + +#endif diff --git a/hw/kdrive/src/Makefile.am b/hw/kdrive/src/Makefile.am index 103ec4ef2..5ef155ae0 100644 --- a/hw/kdrive/src/Makefile.am +++ b/hw/kdrive/src/Makefile.am @@ -6,6 +6,8 @@ noinst_LIBRARIES = libkdrive.a libkdrive_a_SOURCES = \ kaa.c \ + kaa.h \ + kaapict.c \ kasync.c \ kcmap.c \ kcurscol.c \ diff --git a/hw/kdrive/src/kaa.c b/hw/kdrive/src/kaa.c index c9a72a95d..a13e258aa 100644 --- a/hw/kdrive/src/kaa.c +++ b/hw/kdrive/src/kaa.c @@ -28,8 +28,9 @@ #include <config.h> #endif #include "kdrive.h" -#include "fontstruct.h" -#include "dixfontstr.h" +#include "kaa.h" +#include "fontstruct.h" +#include "dixfontstr.h" #define DEBUG_MIGRATE 0 #define DEBUG_PIXMAP 0 @@ -48,30 +49,11 @@ int kaaGeneration; int kaaScreenPrivateIndex; int kaaPixmapPrivateIndex; -typedef struct { - KaaScreenInfoPtr info; -} KaaScreenPrivRec, *KaaScreenPrivPtr; - -typedef struct { - KdOffscreenArea *area; - int score; - int devKind; - DevUnion devPrivate; -} KaaPixmapPrivRec, *KaaPixmapPrivPtr; - #define KAA_PIXMAP_SCORE_MOVE_IN 10 #define KAA_PIXMAP_SCORE_MAX 20 #define KAA_PIXMAP_SCORE_MOVE_OUT -10 #define KAA_PIXMAP_SCORE_MIN -20 -#define KaaGetScreenPriv(s) ((KaaScreenPrivPtr)(s)->devPrivates[kaaScreenPrivateIndex].ptr) -#define KaaScreenPriv(s) KaaScreenPrivPtr pKaaScr = KaaGetScreenPriv(s) - -#define KaaGetPixmapPriv(p) ((KaaPixmapPrivPtr)(p)->devPrivates[kaaPixmapPrivateIndex].ptr) -#define KaaSetPixmapPriv(p,a) ((p)->devPrivates[kaaPixmapPrivateIndex].ptr = (pointer) (a)) -#define KaaPixmapPriv(p) KaaPixmapPrivPtr pKaaPixmap = KaaGetPixmapPriv(p) -#define KaaPixmapPitch(pitch) (((pitch) + (pKaaScr->info->offscreenPitch - 1)) & ~(pKaaScr->info->offscreenPitch - 1)) - #define MIN_OFFPIX_SIZE (4096) static void @@ -127,7 +109,7 @@ kaaPixmapAllocArea (PixmapPtr pPixmap) pKaaPixmap->devKind = pPixmap->devKind; pKaaPixmap->devPrivate = pPixmap->devPrivate; - pKaaPixmap->area = KdOffscreenAlloc (pScreen, pitch * h * (bpp >> 3), + pKaaPixmap->area = KdOffscreenAlloc (pScreen, pitch * h, pKaaScr->info->offscreenByteAlign, FALSE, kaaPixmapSave, (pointer) pPixmap); @@ -140,7 +122,7 @@ kaaPixmapAllocArea (PixmapPtr pPixmap) KaaGetPixmapPriv(pPixmap)->area->offset : -1, pPixmap->drawable.width, pPixmap->drawable.height)); - pPixmap->devKind = pitch * (bpp >> 3); + pPixmap->devKind = pitch; pPixmap->devPrivate.ptr = (pointer) ((CARD8 *) pScreenPriv->screen->memory_base + pKaaPixmap->area->offset); pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; return TRUE; @@ -153,7 +135,6 @@ kaaMoveInPixmap (PixmapPtr pPixmap) unsigned char *dst, *src; int i; - return; KdCheckSync (pPixmap->drawable.pScreen); DBG_MIGRATE (("-> 0x%08x (0x%x) (%dx%d)\n", @@ -201,7 +182,7 @@ kaaMoveOutPixmap (PixmapPtr pPixmap) } } -static void +void kaaPixmapUseScreen (PixmapPtr pPixmap) { KaaPixmapPriv (pPixmap); @@ -215,7 +196,7 @@ kaaPixmapUseScreen (PixmapPtr pPixmap) } } -static void +void kaaPixmapUseMemory (PixmapPtr pPixmap) { KaaPixmapPriv (pPixmap); @@ -271,6 +252,7 @@ kaaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth) break; } } + pPixmap = fbCreatePixmapBpp (pScreen, w, h, depth, bpp); if (!pPixmap) return NULL; @@ -278,13 +260,12 @@ kaaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth) pKaaPixmap->score = 0; pKaaPixmap->area = NULL; - if (depth == pScreen->rootDepth && - (pPixmap->devKind * h) >= MIN_OFFPIX_SIZE) + if ((pPixmap->devKind * h) >= MIN_OFFPIX_SIZE) kaaPixmapAllocArea (pPixmap); return pPixmap; } -static Bool +Bool kaaPixmapIsOffscreen(PixmapPtr p) { ScreenPtr pScreen = p->drawable.pScreen; @@ -295,7 +276,7 @@ kaaPixmapIsOffscreen(PixmapPtr p) pScreenPriv->screen->memory_size); } -static PixmapPtr +PixmapPtr kaaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp) { PixmapPtr pPixmap; @@ -326,7 +307,7 @@ kaaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp) return NULL; } -static Bool +Bool kaaDrawableIsOffscreen (DrawablePtr pDrawable) { PixmapPtr pPixmap; @@ -421,7 +402,7 @@ kaaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, KdMarkSync(pDrawable->pScreen); } -static void +void kaaCopyNtoN (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, @@ -936,73 +917,6 @@ kaaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what) KdCheckPaintWindow (pWin, pRegion, what); } -#ifdef RENDER -#include "mipict.h" - -static void -kaaComposite(CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height) -{ - if (op == PictOpSrc && !pMask) - { - /* - * Check for two special cases -- solid fill and copy area - */ - if (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 && - pSrc->repeat) - { - ; - } - else if (!pSrc->repeat && pSrc->format == pDst->format) - { - RegionRec region; - - xDst += pDst->pDrawable->x; - yDst += pDst->pDrawable->y; - xSrc += pSrc->pDrawable->x; - ySrc += pSrc->pDrawable->y; - if (pMask) - { - xMask += pMask->pDrawable->x; - yMask += pMask->pDrawable->y; - } - if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, - xSrc, ySrc, xMask, yMask, xDst, yDst, - width, height)) - return; - - - kaaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, 0, - REGION_RECTS(®ion), REGION_NUM_RECTS(®ion), - xSrc - xDst, ySrc - yDst, - FALSE, FALSE, 0, 0); - return; - } - } - if (pSrc->pDrawable->type == DRAWABLE_PIXMAP) - kaaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable); - if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP) - kaaPixmapUseMemory ((PixmapPtr) pMask->pDrawable); -#if 0 - if (pDst->pDrawable->type == DRAWABLE_PIXMAP) - kaaPixmapUseMemory ((PixmapPtr) pDst->pDrawable); -#endif - - KdCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc, - xMask, yMask, xDst, yDst, width, height); -} -#endif - Bool kaaDrawInit (ScreenPtr pScreen, KaaScreenInfoPtr pScreenInfo) diff --git a/hw/kdrive/src/kaa.h b/hw/kdrive/src/kaa.h new file mode 100644 index 000000000..5e4d1a315 --- /dev/null +++ b/hw/kdrive/src/kaa.h @@ -0,0 +1,95 @@ +/* + * $RCSId$ + * + * Copyright © 2001 Keith Packard + * + * Partly based on code that is Copyright © The XFree86 Project Inc. + * + * 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 Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD 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. + */ + +#ifndef _KAA_H_ +#define _KAA_H_ + +#define KaaGetScreenPriv(s) ((KaaScreenPrivPtr)(s)->devPrivates[kaaScreenPrivateIndex].ptr) +#define KaaScreenPriv(s) KaaScreenPrivPtr pKaaScr = KaaGetScreenPriv(s) + +#define KaaGetPixmapPriv(p) ((KaaPixmapPrivPtr)(p)->devPrivates[kaaPixmapPrivateIndex].ptr) +#define KaaSetPixmapPriv(p,a) ((p)->devPrivates[kaaPixmapPrivateIndex].ptr = (pointer) (a)) +#define KaaPixmapPriv(p) KaaPixmapPrivPtr pKaaPixmap = KaaGetPixmapPriv(p) +#define KaaPixmapPitch(pitch) (((pitch) + (pKaaScr->info->offscreenPitch - 1)) & ~(pKaaScr->info->offscreenPitch - 1)) + +typedef struct { + KaaScreenInfoPtr info; +} KaaScreenPrivRec, *KaaScreenPrivPtr; + +typedef struct { + KdOffscreenArea *area; + int score; + int devKind; + DevUnion devPrivate; +} KaaPixmapPrivRec, *KaaPixmapPrivPtr; + +extern int kaaScreenPrivateIndex; +extern int kaaPixmapPrivateIndex; + + +void +kaaPixmapUseScreen (PixmapPtr pPixmap); + +void +kaaPixmapUseMemory (PixmapPtr pPixmap); + +Bool +kaaDrawableIsOffscreen (DrawablePtr pDrawable); + +Bool +kaaPixmapIsOffscreen(PixmapPtr p); + +PixmapPtr +kaaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp); + +void +kaaCopyNtoN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +void +kaaComposite(CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +#endif /* _KAA_H_ */ diff --git a/hw/kdrive/src/kaapict.c b/hw/kdrive/src/kaapict.c new file mode 100644 index 000000000..d63c4cea2 --- /dev/null +++ b/hw/kdrive/src/kaapict.c @@ -0,0 +1,418 @@ +/* + * $RCSId$ + * + * Copyright © 2001 Keith Packard + * + * Partly based on code that is Copyright © The XFree86 Project Inc. + * + * 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 Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "kdrive.h" +#include "kaa.h" + +#ifdef RENDER +#include "mipict.h" + +#define KAA_DEBUG_FALLBACKS 0 + +#if KAA_DEBUG_FALLBACKS +static void kaaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n) +{ + char format[20]; + char size[20]; + char loc; + int temp; + + if (!pict) { + snprintf(string, n, "None"); + return; + } + + switch (pict->format) + { + case PICT_a8r8g8b8: + snprintf(format, 20, "ARGB8888"); + break; + case PICT_r5g6b5: + snprintf(format, 20, "RGB565 "); + break; + case PICT_x1r5g5b5: + snprintf(format, 20, "RGB555 "); + break; + case PICT_a8: + snprintf(format, 20, "A8 "); + break; + default: + snprintf(format, 20, "0x%x", (int)pict->format); + break; + } + + loc = kaaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm'; + + snprintf(size, 20, "%dx%d%s", pict->pDrawable->width, + pict->pDrawable->height, pict->repeat ? + " R" : ""); + + snprintf(string, n, "0x%lx:%c fmt %s (%s)", (long)pict, loc, format, size); +} + +static void +kaaPrintCompositeFallback(CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst) +{ + char sop[20]; + + char srcdesc[40], maskdesc[40], dstdesc[40]; + + switch(op) + { + case PictOpSrc: + sprintf(sop, "Src"); + break; + case PictOpOver: + sprintf(sop, "Over"); + break; + default: + sprintf(sop, "0x%x", (int)op); + break; + } + + kaaCompositeFallbackPictDesc(pSrc, srcdesc, 40); + kaaCompositeFallbackPictDesc(pMask, maskdesc, 40); + kaaCompositeFallbackPictDesc(pDst, dstdesc, 40); + + ErrorF("Composite fallback: op %s, \n" + " src %s, \n" + " mask %s, \n" + " dst %s, \n", + sop, srcdesc, maskdesc, dstdesc); +} +#endif + +static Bool +kaaGetPixelFromRGBA(CARD32 *pixel, + CARD16 red, + CARD16 green, + CARD16 blue, + CARD16 alpha, + CARD32 format) +{ + int rbits, bbits, gbits, abits; + int rshift, bshift, gshift, ashift; + + *pixel = 0; + + if (!PICT_FORMAT_COLOR(format)) + return FALSE; + + rbits = PICT_FORMAT_R(format); + gbits = PICT_FORMAT_G(format); + bbits = PICT_FORMAT_B(format); + abits = PICT_FORMAT_A(format); + + if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { + bshift = 0; + gshift = bbits; + rshift = gshift + gbits; + ashift = rshift + rbits; + } else { /* PICT_TYPE_ABGR */ + rshift = 0; + gshift = rbits; + bshift = gshift + gbits; + ashift = bshift + bbits; + } + + *pixel |= ( blue >> (16 - bbits)) << bshift; + *pixel |= ( red >> (16 - rbits)) << rshift; + *pixel |= (green >> (16 - gbits)) << gshift; + *pixel |= (alpha >> (16 - abits)) << ashift; + + return TRUE; +} + + +static Bool +kaaGetRGBAFromPixel(CARD32 pixel, + CARD16 *red, + CARD16 *green, + CARD16 *blue, + CARD16 *alpha, + CARD32 format) +{ + int rbits, bbits, gbits, abits; + int rshift, bshift, gshift, ashift; + + if (!PICT_FORMAT_COLOR(format)) + return FALSE; + + rbits = PICT_FORMAT_R(format); + gbits = PICT_FORMAT_G(format); + bbits = PICT_FORMAT_B(format); + abits = PICT_FORMAT_A(format); + + if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { + bshift = 0; + gshift = bbits; + rshift = gshift + gbits; + ashift = rshift + rbits; + } else { /* PICT_TYPE_ABGR */ + rshift = 0; + gshift = rbits; + bshift = gshift + gbits; + ashift = bshift + bbits; + } + + *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits); + while (rbits < 16) { + *red |= *red >> rbits; + rbits <<= 1; + } + + *green = ((pixel >> gshift ) & ((1 << gbits) - 1)) << (16 - gbits); + while (gbits < 16) { + *green |= *green >> gbits; + gbits <<= 1; + } + + *blue = ((pixel >> bshift ) & ((1 << bbits) - 1)) << (16 - bbits); + while (bbits < 16) { + *blue |= *blue >> bbits; + bbits <<= 1; + } + + if (abits) { + *alpha = ((pixel >> ashift ) & ((1 << abits) - 1)) << (16 - abits); + while (abits < 16) { + *alpha |= *alpha >> abits; + abits <<= 1; + } + } else + *alpha = 0xffff; + + return TRUE; +} + +void +kaaComposite(CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + KdScreenPriv (pDst->pDrawable->pScreen); + KaaScreenPriv (pDst->pDrawable->pScreen); + + if (!pMask) + { + if (op == PictOpSrc) + { + if (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 && + pSrc->repeat) + { + /* Solid fill case */ + RegionRec region; + BoxPtr pbox; + int nbox; + int dst_off_x, dst_off_y; + PixmapPtr pSrcPix, pDstPix; + CARD32 pixel; + CARD16 red, green, blue, alpha; + + xDst += pDst->pDrawable->x; + yDst += pDst->pDrawable->y; + xSrc += pSrc->pDrawable->x; + ySrc += pSrc->pDrawable->y; + + if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, + xSrc, ySrc, xMask, yMask, xDst, yDst, + width, height)) + return; + + if (pSrc->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable); + if (pDst->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseScreen ((PixmapPtr) pDst->pDrawable); + + pDstPix = kaaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, + &dst_off_y); + if (!pDstPix) + goto software2; + + if (pSrc->pDrawable->type == DRAWABLE_WINDOW) + pSrcPix = (*pSrc->pDrawable->pScreen->GetWindowPixmap)( + (WindowPtr) (pSrc->pDrawable)); + else + pSrcPix = (PixmapPtr) (pSrc->pDrawable); + + /* If source is offscreen, we need to sync the accelerator + * before accessing it. We'd prefer for it to be in memory. + */ + if (kaaPixmapIsOffscreen(pSrcPix)) { + KdCheckSync(pDst->pDrawable->pScreen); + } + + pixel = *(CARD32 *)(pSrcPix->devPrivate.ptr); + if (!kaaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha, + pSrc->format)) + goto software; + kaaGetPixelFromRGBA(&pixel, red, green, blue, alpha, + pDst->format); + + if (!(*pKaaScr->info->PrepareSolid) (pDstPix, GXcopy, 0xffffff, + pixel)) + { + goto software; + } + + nbox = REGION_NUM_RECTS(®ion); + pbox = REGION_RECTS(®ion); + while (nbox--) + { + (*pKaaScr->info->Solid) (pbox->x1 + dst_off_x, + pbox->y1 + dst_off_y, + pbox->x2 + dst_off_x, + pbox->y2 + dst_off_y); + pbox++; + } + + (*pKaaScr->info->DoneSolid) (); + KdMarkSync(pDst->pDrawable->pScreen); + + return; + } + else if (!pSrc->repeat && pSrc->format == pDst->format) + { + /* Copy area case */ + RegionRec region; + + xDst += pDst->pDrawable->x; + yDst += pDst->pDrawable->y; + xSrc += pSrc->pDrawable->x; + ySrc += pSrc->pDrawable->y; + + if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, + xSrc, ySrc, xMask, yMask, xDst, yDst, + width, height)) + return; + + + kaaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, 0, + REGION_RECTS(®ion), REGION_NUM_RECTS(®ion), + xSrc - xDst, ySrc - yDst, + FALSE, FALSE, 0, 0); + return; + } + } + + if (pScreenPriv->enabled && pKaaScr->info->PrepareBlend && + !pSrc->alphaMap && !pDst->alphaMap) + { + /* Blend case */ + RegionRec region; + BoxPtr pbox; + int nbox; + int src_off_x, src_off_y, dst_off_x, dst_off_y; + PixmapPtr pSrcPix, pDstPix; + + xDst += pDst->pDrawable->x; + yDst += pDst->pDrawable->y; + + xSrc += pSrc->pDrawable->x; + ySrc += pSrc->pDrawable->y; + + if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, + xSrc, ySrc, xMask, yMask, xDst, yDst, + width, height)) + return; + + + /* Migrate pixmaps to same place as destination */ + if (pSrc->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseScreen ((PixmapPtr) pSrc->pDrawable); + if (pDst->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseScreen ((PixmapPtr) pDst->pDrawable); + + pSrcPix = kaaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, + &src_off_y); + pDstPix = kaaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, + &dst_off_y); + if (!pSrcPix || !pDstPix) + goto software2; + if (!(*pKaaScr->info->PrepareBlend) (op, pSrc, pDst, pSrcPix, + pDstPix)) + { + goto software; + } + + nbox = REGION_NUM_RECTS(®ion); + pbox = REGION_RECTS(®ion); + + xSrc -= xDst; + ySrc -= yDst; + + while (nbox--) + { + (*pKaaScr->info->Blend) (pbox->x1 + xSrc + src_off_x, + pbox->y1 + ySrc + src_off_y, + pbox->x1 + dst_off_x, + pbox->y1 + dst_off_y, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + pbox++; + } + + (*pKaaScr->info->DoneBlend) (); + KdMarkSync(pDst->pDrawable->pScreen); + + return; + } + } + +software: + if (pSrc->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable); + if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseMemory ((PixmapPtr) pMask->pDrawable); +#if 0 + if (pDst->pDrawable->type == DRAWABLE_PIXMAP) + kaaPixmapUseMemory ((PixmapPtr) pDst->pDrawable); +#endif + +software2: +#if KAA_DEBUG_FALLBACKS + kaaPrintCompositeFallback (op, pSrc, pMask, pDst); +#endif + + KdCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc, + xMask, yMask, xDst, yDst, width, height); +} +#endif diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h index df2ead9f4..9bde73d21 100644 --- a/hw/kdrive/src/kdrive.h +++ b/hw/kdrive/src/kdrive.h @@ -332,6 +332,19 @@ typedef struct _KaaScreenInfo { int offscreenByteAlign; int offscreenPitch; int flags; + + Bool (*PrepareBlend) (int op, + PicturePtr pSrcPicture, + PicturePtr pDstPicture, + PixmapPtr pSrc, + PixmapPtr pDst); + void (*Blend) (int srcX, + int srcY, + int dstX, + int dstY, + int width, + int height); + void (*DoneBlend) (void); } KaaScreenInfoRec, *KaaScreenInfoPtr; #define KAA_OFFSCREEN_PIXMAPS (1 << 0) |