summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2003-12-29 06:24:01 +0000
committerEric Anholt <anholt@freebsd.org>2003-12-29 06:24:01 +0000
commitdf03e80ae9162ec87f503322ccbcf2846ad38bef (patch)
tree687daa27cf3702e04e9f2c016c4c0680ddda8b2e /hw
parent9bea538745f1a0c14faaac0e61dee5cf86f98dc6 (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.am23
-rw-r--r--hw/kdrive/ati/ati.c282
-rw-r--r--hw/kdrive/ati/ati.h113
-rw-r--r--hw/kdrive/ati/ati_draw.c486
-rw-r--r--hw/kdrive/ati/ati_draw.h82
-rw-r--r--hw/kdrive/ati/ati_drawtmp.h241
-rw-r--r--hw/kdrive/ati/ati_dri.c929
-rw-r--r--hw/kdrive/ati/ati_dri.h100
-rw-r--r--hw/kdrive/ati/ati_dripriv.h58
-rw-r--r--hw/kdrive/ati/ati_reg.h138
-rw-r--r--hw/kdrive/ati/ati_sarea.h42
-rw-r--r--hw/kdrive/ati/ati_stub.c23
-rw-r--r--hw/kdrive/ati/r128_blendtmp.h125
-rw-r--r--hw/kdrive/ati/r128_common.h171
-rw-r--r--hw/kdrive/ati/r128_sarea.h186
-rw-r--r--hw/kdrive/ati/radeon_common.h461
-rw-r--r--hw/kdrive/ati/radeon_sarea.h222
-rw-r--r--hw/kdrive/src/Makefile.am2
-rw-r--r--hw/kdrive/src/kaa.c112
-rw-r--r--hw/kdrive/src/kaa.h95
-rw-r--r--hw/kdrive/src/kaapict.c418
-rw-r--r--hw/kdrive/src/kdrive.h13
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 (&region, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask, xDst, yDst,
- width, height))
- return;
-
-
- kaaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, 0,
- REGION_RECTS(&region), REGION_NUM_RECTS(&region),
- 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 (&region, 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(&region);
+ pbox = REGION_RECTS(&region);
+ 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 (&region, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height))
+ return;
+
+
+ kaaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, 0,
+ REGION_RECTS(&region), REGION_NUM_RECTS(&region),
+ 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 (&region, 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(&region);
+ pbox = REGION_RECTS(&region);
+
+ 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)