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.
This commit is contained in:
Eric Anholt 2003-12-29 06:24:01 +00:00
parent 9bea538745
commit df03e80ae9
22 changed files with 3892 additions and 460 deletions

View File

@ -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@ \

View File

@ -27,130 +27,140 @@
#include <config.h>
#endif
#include "ati.h"
#include "ati_reg.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}
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;

View File

@ -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;
int datatype;
int dp_gui_master_cntl;
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 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_ */

View File

@ -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,191 +216,206 @@ 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;
ATIScreenInfo(pScreenPriv);
int ret;
mmio = atic->reg_base;
if (atic->is_radeon)
ret = drmCommandNone(atic->drmFd, DRM_RADEON_CP_START);
else
ret = drmCommandNone(atic->drmFd, DRM_R128_CCE_START);
/* 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);
}
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));
return TRUE;
if (ret == 0)
atis->using_dma = TRUE;
else
ErrorF("%s: DMA start returned %d\n", __FUNCTION__, ret);
}
/* 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(pScreen);
ATICardInfo(pScreenPriv);
ATIScreenInfo(pScreenPriv);
drmRadeonCPStop stop;
int ret;
stop.flush = 1;
stop.idle = 1;
ret = drmCommandWrite(atic->drmFd, DRM_RADEON_CP_STOP, &stop,
sizeof(drmRadeonCPStop));
if (ret != 0 && errno == EBUSY) {
ErrorF("Failed to idle the DMA engine\n");
stop.idle = 0;
ret = drmCommandWrite(atic->drmFd, DRM_RADEON_CP_STOP, &stop,
sizeof(drmRadeonCPStop));
}
atis->using_dma = FALSE;
}
/* 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));
}
/* Flush the indirect buffer to the kernel for submission to the card */
void ATIDMAFlushIndirect(Bool discard)
{
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;
}
}
/* 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
ATIPrepareSolid(PixmapPtr pPixmap, int alu, Pixel pm, Pixel fg)
R128GetDatatypePict(CARD32 format, CARD32 *type)
{
KdScreenPriv(pPixmap->drawable.pScreen);
ATIScreenInfo(pScreenPriv);
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;
switch (format) {
case PICT_a8r8g8b8:
*type = R128_DATATYPE_ARGB_8888;
return TRUE;
case PICT_r5g6b5:
*type = R128_DATATYPE_RGB_565;
return TRUE;
}
if (!ATISetup(pPixmap, NULL))
ErrorF ("Unsupported format: %x\n", format);
return FALSE;
}
/* 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)
{
is_24bpp = FALSE;
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;
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);
return TRUE;
}
static void
ATISolid(int x1, int y1, int x2, int y2)
{
if (is_24bpp) {
x1 *= 3;
x2 *= 3;
}
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));
}
#ifdef USE_DRI
#define USE_DMA
#include "ati_drawtmp.h"
#include "r128_blendtmp.h"
#endif /* USE_DRI */
#undef USE_DMA
#include "ati_drawtmp.h"
#include "r128_blendtmp.h"
static void
ATIDoneSolid(void)
{
}
static Bool
ATIPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu, Pixel pm)
{
KdScreenPriv(pDst->drawable.pScreen);
ATIScreenInfo(pScreenPriv);
copydx = dx;
copydy = dy;
if (is_24bpp && pm != 0xffffffff)
return FALSE;
if (!ATISetup(pDst, pSrc))
return FALSE;
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));
return TRUE;
}
static void
ATICopy(int srcX, int srcY, int dstX, int dstY, int w, int h)
{
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;
}
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);
}
static void
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;
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 */
switch (pScreenPriv->screen->fb[0].depth)
{
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;
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;
}
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;
} 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;
#else
{
#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;
}
}
if (!kaaDrawInit(pScreen, &ATIKaa))
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 {
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, &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();
}

82
hw/kdrive/ati/ati_draw.h Normal file
View File

@ -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_ */

241
hw/kdrive/ati/ati_drawtmp.h Normal file
View File

@ -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

929
hw/kdrive/ati/ati_dri.c Normal file
View File

@ -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;
}

100
hw/kdrive/ati/ati_dri.h Normal file
View File

@ -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_ */

View File

@ -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

View File

@ -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)

42
hw/kdrive/ati/ati_sarea.h Normal file
View File

@ -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_ */

View File

@ -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);
}
}

View File

@ -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

171
hw/kdrive/ati/r128_common.h Normal file
View File

@ -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

186
hw/kdrive/ati/r128_sarea.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -6,6 +6,8 @@ noinst_LIBRARIES = libkdrive.a
libkdrive_a_SOURCES = \
kaa.c \
kaa.h \
kaapict.c \
kasync.c \
kcmap.c \
kcurscol.c \

View File

@ -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)

95
hw/kdrive/src/kaa.h Normal file
View File

@ -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_ */

418
hw/kdrive/src/kaapict.c Normal file
View File

@ -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

View File

@ -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)