summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver')
-rw-r--r--xc/programs/Xserver/GL/dri/dri.c16
-rw-r--r--xc/programs/Xserver/GL/dri/dri.h3
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile1
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h8
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h87
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c313
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h3
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h5
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c32
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h246
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h25
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Imakefile1
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h4
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c162
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h123
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c23
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h80
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c1202
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h4
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h10
20 files changed, 1483 insertions, 865 deletions
diff --git a/xc/programs/Xserver/GL/dri/dri.c b/xc/programs/Xserver/GL/dri/dri.c
index 256a16986..e74aef391 100644
--- a/xc/programs/Xserver/GL/dri/dri.c
+++ b/xc/programs/Xserver/GL/dri/dri.c
@@ -844,14 +844,26 @@ DRIClipNotifyAllDrawables(ScreenPtr pScreen)
static void
DRITransitionToSharedBuffers(ScreenPtr pScreen)
{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
DRIClipNotifyAllDrawables( pScreen );
+
+ if (pDRIInfo->TransitionSingleToMulti3D)
+ pDRIInfo->TransitionSingleToMulti3D( pScreen );
}
static void
DRITransitionToPrivateBuffers(ScreenPtr pScreen)
{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
DRIClipNotifyAllDrawables( pScreen );
+
+ if (pDRIInfo->TransitionMultiToSingle3D)
+ pDRIInfo->TransitionMultiToSingle3D( pScreen );
}
@@ -861,6 +873,8 @@ DRITransitionTo3d(ScreenPtr pScreen)
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+ DRIClipNotifyAllDrawables( pScreen );
+
if (pDRIInfo->TransitionTo3d)
pDRIInfo->TransitionTo3d( pScreen );
}
@@ -871,6 +885,8 @@ DRITransitionTo2d(ScreenPtr pScreen)
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+ DRIClipNotifyAllDrawables( pScreen );
+
if (pDRIInfo->TransitionTo2d)
pDRIInfo->TransitionTo2d( pScreen );
}
diff --git a/xc/programs/Xserver/GL/dri/dri.h b/xc/programs/Xserver/GL/dri/dri.h
index db1be779d..223162ce6 100644
--- a/xc/programs/Xserver/GL/dri/dri.h
+++ b/xc/programs/Xserver/GL/dri/dri.h
@@ -121,6 +121,9 @@ typedef struct {
CARD32 indx);
void (*TransitionTo3d)(ScreenPtr pScreen);
void (*TransitionTo2d)(ScreenPtr pScreen);
+ void (*TransitionSingleToMulti3D)(ScreenPtr pScreen);
+ void (*TransitionMultiToSingle3D)(ScreenPtr pScreen);
+
void (*SetDrawableIndex)(WindowPtr pWin, CARD32 indx);
Bool (*OpenFullScreen)(ScreenPtr pScreen);
Bool (*CloseFullScreen)(ScreenPtr pScreen);
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile
index 68694423a..078fdc18d 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile
@@ -185,6 +185,7 @@ INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(XF86SRC) \
-I$(XF86SRC)/vgahw -I$(XF86SRC)/fbdevhw \
-I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb \
-I$(SERVERSRC)/fb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/miext/shadow \
-I$(SERVERSRC)/render -I$(SERVERSRC)/Xext -I$(SERVERSRC)/include \
$(DRIINCLUDES) -I$(FONTINCSRC) -I$(EXTINCSRC) -I$(XINCLUDESRC)
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h
index 08b5ee810..0e96df10e 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h
@@ -369,6 +369,10 @@ typedef struct {
unsigned char *PCI; /* Map */
Bool depthMoves; /* Enable depth moves -- slow! */
+
+ Bool allowPageFlip; /* Enable 3d page flipping */
+ Bool have3DWindows; /* Are there any 3d clients? */
+ int drmMinor;
drmSize agpSize;
drmHandle agpMemHandle; /* Handle from drmAgpAlloc */
@@ -451,10 +455,6 @@ typedef struct {
CARD32 re_width_height;
CARD32 aux_sc_cntl;
-
-#ifdef PER_CONTEXT_SAREA
- int perctx_sarea_size;
-#endif
#endif
XF86VideoAdaptorPtr adaptor;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h
index 89f92cc8f..ec789af39 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_common.h
@@ -38,6 +38,8 @@
#ifndef _RADEON_COMMON_H_
#define _RADEON_COMMON_H_
+#include "xf86drm.h"
+
/* WARNING: If you change any of these defines, make sure to change
* the kernel include file as well (radeon_drm.h)
*/
@@ -62,6 +64,7 @@
#define DRM_RADEON_VERTEX2 0x0f
#define DRM_RADEON_CMDBUF 0x10
#define DRM_RADEON_GETPARAM 0x11
+#define DRM_RADEON_FLIP 0x12
#define DRM_RADEON_MAX_DRM_COMMAND_INDEX 0x39
@@ -229,6 +232,15 @@ typedef struct {
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;
@@ -250,4 +262,79 @@ typedef struct {
#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 RADEON_MAX_STATE_PACKETS 21
+
+
+/* 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 */
+
+typedef union {
+ int i;
+ struct {
+ char cmd_type, pad0, pad1, pad2;
+ } header;
+ struct {
+ char cmd_type, packet_id, pad0, pad1;
+ } packet;
+ struct {
+ char cmd_type, offset, stride, count;
+ } scalars;
+ struct {
+ char cmd_type, offset, stride, count;
+ } vectors;
+ struct {
+ char cmd_type, buf_idx, pad0, pad1;
+ } dma;
+} drmRadeonCmdHeader;
+
+
+
+typedef struct drm_radeon_getparam {
+ int param;
+ int *value;
+} drmRadeonGetParam;
+
+#define RADEON_PARAM_AGP_BUFFER_OFFSET 0x1
+
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c
index aead524be..e16e79481 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c
@@ -46,6 +46,8 @@
#include "xf86.h"
#include "windowstr.h"
+
+#include "shadow.h"
/* GLX/DRI/DRM definitions */
#define _XF86DRI_SERVER_
#include "GL/glxtokens.h"
@@ -68,6 +70,16 @@
# define DRM_PAGE_SIZE 4096
#endif
+
+static Bool RADEONDRICloseFullScreen(ScreenPtr pScreen);
+static Bool RADEONDRIOpenFullScreen(ScreenPtr pScreen);
+static void RADEONDRITransitionTo2d(ScreenPtr pScreen);
+static void RADEONDRITransitionTo3d(ScreenPtr pScreen);
+static void RADEONDRITransitionMultiToSingle3d(ScreenPtr pScreen);
+static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen);
+
+static void RADEONDRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf);
+
/* Initialize the visual configs that are supported by the hardware.
These are combined with the visual configs that the indirect
rendering core supports, and the intersection is exported to the
@@ -262,36 +274,6 @@ static Bool RADEONCreateContext(ScreenPtr pScreen, VisualPtr visual,
drmContext hwContext, void *pVisualConfigPriv,
DRIContextType contextStore)
{
-#ifdef PER_CONTEXT_SAREA
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONDRIContextPtr ctx_info;
-
- ctx_info = (RADEONDRIContextPtr)contextStore;
- if (!ctx_info) return FALSE;
-
- if (drmAddMap(info->drmFD, 0,
- info->perctx_sarea_size,
- DRM_SHM,
- DRM_REMOVABLE,
- &ctx_info->sarea_handle) < 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[dri] could not create private sarea for ctx id (%d)\n",
- (int)hwContext);
- return FALSE;
- }
-
- if (drmAddContextPrivateMapping(info->drmFD, hwContext,
- ctx_info->sarea_handle) < 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[dri] could not associate private sarea to ctx id (%d)\n",
- (int)hwContext);
- drmRmMap(info->drmFD, ctx_info->sarea_handle);
- return FALSE;
- }
-
- ctx_info->ctx_id = hwContext;
-#endif
return TRUE;
}
@@ -299,20 +281,6 @@ static Bool RADEONCreateContext(ScreenPtr pScreen, VisualPtr visual,
static void RADEONDestroyContext(ScreenPtr pScreen, drmContext hwContext,
DRIContextType contextStore)
{
-#ifdef PER_CONTEXT_SAREA
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONDRIContextPtr ctx_info;
-
- ctx_info = (RADEONDRIContextPtr) contextStore;
- if (!ctx_info) return;
-
- if (drmRmMap(info->drmFD, ctx_info->sarea_handle) < 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[dri] could not remove private sarea for ctx id (%d)\n",
- (int)hwContext);
- }
-#endif
}
/* Called when the X server is woken up to allow the last client's
@@ -720,6 +688,9 @@ static void RADEONDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
info->accel->NeedToSync = TRUE;
}
+
+
+
/* Initialize the AGP state. Request memory for use in AGP space, and
initialize the Radeon registers to point to that memory. */
static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen)
@@ -1179,8 +1150,7 @@ static void RADEONDRISAREAInit(ScreenPtr pScreen,
RADEON_ANTI_ALIAS_NONE);
ctx->rb3d_cntl = (RADEON_PLANE_MASK_ENABLE |
- color_fmt |
- RADEON_ZBLOCK16);
+ color_fmt | (1<<15));
ctx->rb3d_coloroffset = (info->backOffset & RADEON_COLOROFFSET_MASK);
@@ -1237,43 +1207,14 @@ static void RADEONDRISAREAInit(ScreenPtr pScreen,
ctx->se_vport_zscale = 0x00000000;
ctx->se_vport_zoffset = 0x00000000;
- ctx->se_cntl_status = (RADEON_VC_NO_SWAP |
- RADEON_TCL_BYPASS);
-
-#ifdef TCL_ENABLE
- /* FIXME: Obviously these need to be properly initialized */
- ctx->se_tcl_material_emmissive.red = 0x00000000;
- ctx->se_tcl_material_emmissive.green = 0x00000000;
- ctx->se_tcl_material_emmissive.blue = 0x00000000;
- ctx->se_tcl_material_emmissive.alpha = 0x00000000;
-
- ctx->se_tcl_material_ambient.red = 0x00000000;
- ctx->se_tcl_material_ambient.green = 0x00000000;
- ctx->se_tcl_material_ambient.blue = 0x00000000;
- ctx->se_tcl_material_ambient.alpha = 0x00000000;
-
- ctx->se_tcl_material_diffuse.red = 0x00000000;
- ctx->se_tcl_material_diffuse.green = 0x00000000;
- ctx->se_tcl_material_diffuse.blue = 0x00000000;
- ctx->se_tcl_material_diffuse.alpha = 0x00000000;
-
- ctx->se_tcl_material_specular.red = 0x00000000;
- ctx->se_tcl_material_specular.green = 0x00000000;
- ctx->se_tcl_material_specular.blue = 0x00000000;
- ctx->se_tcl_material_specular.alpha = 0x00000000;
-
- ctx->se_tcl_shininess = 0x00000000;
- ctx->se_tcl_output_vtx_fmt = 0x00000000;
- ctx->se_tcl_output_vtx_sel = 0x00000000;
- ctx->se_tcl_matrix_select_0 = 0x00000000;
- ctx->se_tcl_matrix_select_1 = 0x00000000;
- ctx->se_tcl_ucp_vert_blend_ctl = 0x00000000;
- ctx->se_tcl_texture_proc_ctl = 0x00000000;
- ctx->se_tcl_light_model_ctl = 0x00000000;
- for ( i = 0 ; i < 4 ; i++ ) {
- ctx->se_tcl_per_light_ctl[i] = 0x00000000;
+ if (info->IsM6) {
+ ctx->se_cntl_status = (RADEON_VC_NO_SWAP |
+ RADEON_TCL_BYPASS);
}
-#endif
+ else {
+ ctx->se_cntl_status = (RADEON_VC_NO_SWAP);
+ }
+
ctx->re_top_left = ((0 << RADEON_RE_LEFT_SHIFT) |
(0 << RADEON_RE_TOP_SHIFT) );
@@ -1378,29 +1319,12 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
< RADEON_MAX_DRAWABLES
? SAREA_MAX_DRAWABLES
: RADEON_MAX_DRAWABLES);
-#ifdef PER_CONTEXT_SAREA
- /* This is only here for testing per-context SAREAs. When used, the
- magic number below would be properly defined in a header file. */
- info->perctx_sarea_size = 64 * 1024;
-#endif
-#ifdef NOT_DONE
- /* FIXME: Need to extend DRI protocol to pass this size back to
- * client for SAREA mapping that includes a device private record
- */
- pDRIInfo->SAREASize =
- ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */
- /* + shared memory device private rec */
-#else
- /* For now the mapping works by using a fixed size defined
- * in the SAREA header
- */
if (sizeof(XF86DRISAREARec)+sizeof(RADEONSAREAPriv)>SAREA_MAX) {
ErrorF("Data does not fit in SAREA\n");
return FALSE;
}
pDRIInfo->SAREASize = SAREA_MAX;
-#endif
if (!(pRADEONDRI = (RADEONDRIPtr)xcalloc(sizeof(RADEONDRIRec),1))) {
DRIDestroyInfoRec(info->pDRIInfo);
@@ -1417,6 +1341,12 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
pDRIInfo->InitBuffers = RADEONDRIInitBuffers;
pDRIInfo->MoveBuffers = RADEONDRIMoveBuffers;
pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
+ pDRIInfo->OpenFullScreen = RADEONDRIOpenFullScreen;
+ pDRIInfo->CloseFullScreen = RADEONDRICloseFullScreen;
+ pDRIInfo->TransitionTo2d = RADEONDRITransitionTo2d;
+ pDRIInfo->TransitionTo3d = RADEONDRITransitionTo3d;
+ pDRIInfo->TransitionSingleToMulti3D = RADEONDRITransitionSingleToMulti3d;
+ pDRIInfo->TransitionMultiToSingle3D = RADEONDRITransitionMultiToSingle3d;
pDRIInfo->createDummyCtx = TRUE;
pDRIInfo->createDummyCtxPriv = FALSE;
@@ -1493,6 +1423,15 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
RADEONDRICloseScreen(pScreen);
return FALSE;
}
+ if (version->version_minor < 3) {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[dri] Some DRI features disabled because of version mismatch.\n"
+ "[dri] radeon.o kernel module version is %d.%d.%d but 1.1.3 is preferred.\n",
+ version->version_major,
+ version->version_minor,
+ version->version_patchlevel);
+ info->drmMinor = version->version_minor;
+ }
drmFreeVersion(version);
}
@@ -1622,10 +1561,15 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen)
pRADEONDRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
-#ifdef PER_CONTEXT_SAREA
- /* Set per-context SAREA size */
- pRADEONDRI->perctx_sarea_size = info->perctx_sarea_size;
-#endif
+
+ /* Have shadow run only while there is 3d active.
+ */
+ if (info->allowPageFlip /* && info->drmMinor >= 3 */) {
+ shadowSetup (pScreen);
+ shadowAdd( pScreen, 0, RADEONDRIShadowUpdate, 0, 0, 0 );
+ }
+ else
+ info->allowPageFlip = 0;
return TRUE;
}
@@ -1715,3 +1659,166 @@ void RADEONDRICloseScreen(ScreenPtr pScreen)
info->pVisualConfigsPriv = NULL;
}
}
+
+
+
+/* Fullscreen hooks. The DRI fullscreen mode can probably be removed
+ * as it adds little or nothing above the mechanism below. (and isn't
+ * widely used)
+ */
+static Bool
+RADEONDRIOpenFullScreen(ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+static Bool
+RADEONDRICloseFullScreen(ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+
+
+/* Use callbacks from dri.c to support pageflipping mode for a single
+ * 3d context without need for any specific full-screen extension.
+ *
+ * Also see tdfx driver for example of using these callbacks to
+ * allocate and free 3d-specific memory on demand.
+ */
+
+
+/* Use the miext/shadow module to maintain a list of dirty rectangles.
+ * These are blitted to the back buffer to keep both buffers clean
+ * during page-flipping when the 3d application isn't fullscreen.
+ *
+ * Unlike most use of the shadow code, both buffers are in video
+ * memory.
+ *
+ * An alternative to this would be to organize for all on-screen
+ * drawing operations to be duplicated for the two buffers. That
+ * might be faster, but seems like a lot more work...
+ */
+
+
+/* This should be done *before* XAA syncs or fires its buffer.
+ * Otherwise will have to fire it again???
+ */
+static void
+RADEONDRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RegionPtr damage = &pBuf->damage;
+ int i, num = REGION_NUM_RECTS(damage);
+ BoxPtr pbox = REGION_RECTS(damage);
+ RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+
+ /* Don't want to do this when no 3d is active and pages are
+ * right-way-round :
+ */
+ if (!info->allowPageFlip ||
+ (!info->have3DWindows && pSAREAPriv->pfCurrentPage == 0))
+ return;
+
+ (*info->accel->SetupForScreenToScreenCopy)(pScrn,
+ 1, 1, GXcopy,
+ (CARD32)(-1), -1);
+
+ for (i = 0 ; i < num ; i++, pbox++) {
+ (*info->accel->SubsequentScreenToScreenCopy)(pScrn,
+ pbox->x1,
+ pbox->y1,
+ pbox->x1 + info->backX,
+ pbox->y1 + info->backY,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+
+ }
+}
+
+
+static void
+RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen)
+{
+ /* Tell the clients not to pageflip. How?
+ * -- Field in sarea, plus bumping the window counters.
+ * -- DRM needs to cope with Front-to-Back swapbuffers.
+ */
+ RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+ pSAREAPriv->pfAllowPageFlip = 0;
+}
+
+static void
+RADEONDRITransitionMultiToSingle3d(ScreenPtr pScreen)
+{
+ /* Let the remaining 3d app start page flipping again.
+ */
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+
+ if (info->allowPageFlip)
+ pSAREAPriv->pfAllowPageFlip = 1;
+}
+
+
+static void
+RADEONDRITransitionTo3d(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+
+ /* Do we have to repair the back buffer?
+ */
+ if (info->allowPageFlip && !pSAREAPriv->pfAllowPageFlip) {
+ /* Duplicate the frontbuffer to the backbuffer:
+ */
+ (*info->accel->SetupForScreenToScreenCopy)(pScrn,
+ 1, 1, GXcopy,
+ (CARD32)(-1), -1);
+
+ (*info->accel->SubsequentScreenToScreenCopy)(pScrn,
+ 0,
+ 0,
+ info->backX,
+ info->backY,
+ pScrn->virtualX,
+ pScrn->virtualY);
+
+ pSAREAPriv->pfAllowPageFlip = 1;
+ }
+
+ info->have3DWindows = 1;
+}
+
+
+static void
+RADEONDRITransitionTo2d(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+
+ /* Go back to the front buffer if things were left in a flipped state.
+ */
+ if (pSAREAPriv->pfCurrentPage != 0) {
+ /* Won't work as we're not holding the lock at this point:
+ */
+/* drmRadeonFlipBuffers( info->drmFD ); */
+ }
+
+ /* Shut down shadowing if we've made it back to the front page:
+ */
+ if (pSAREAPriv->pfCurrentPage == 0) {
+ pSAREAPriv->pfAllowPageFlip = 0;
+ }
+/* else */
+/* xf86DrvMsg(pScreen->myNum, X_WARNING, */
+/* "[dri] RADEONDRITransitionTo2d failed to unflip buffers.\n"); */
+
+ info->have3DWindows = 0;
+}
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h
index 4a4f53724..35c34693b 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h
@@ -98,9 +98,6 @@ typedef struct {
int agpTexOffset;
unsigned int sarea_priv_offset;
-#ifdef PER_CONTEXT_SAREA
- drmSize perctx_sarea_size;
-#endif
} RADEONDRIRec, *RADEONDRIPtr;
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h
index 530fd4abb..68f139a42 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h
@@ -52,13 +52,8 @@ typedef struct {
} RADEONConfigPrivRec, *RADEONConfigPrivPtr;
typedef struct {
-#ifdef PER_CONTEXT_SAREA
- drmContext ctx_id;
- drmHandle sarea_handle;
-#else
/* Nothing here yet */
int dummy;
-#endif
} RADEONDRIContextRec, *RADEONDRIContextPtr;
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
index e60f081ce..63f405701 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
@@ -52,7 +52,7 @@
* This server does not yet support these XFree86 4.0 features:
* !!!! FIXME !!!!
* DDC1 & DDC2
- * shadowfb
+ * shadowfb (Note: dri uses shadow for another purpose in radeon_dri.c)
* overlay planes
*
* Modified by Marc Aurele La France (tsi@xfree86.org) for ATI driver merge.
@@ -130,6 +130,7 @@ typedef enum {
OPTION_RING_SIZE,
OPTION_BUFFER_SIZE,
OPTION_DEPTH_MOVE,
+ OPTION_PAGE_FLIP,
#endif
OPTION_CRT_SCREEN,
OPTION_PANEL_SIZE,
@@ -150,6 +151,7 @@ const OptionInfoRec RADEONOptions[] = {
{ OPTION_RING_SIZE, "RingSize", OPTV_INTEGER, {0}, FALSE },
{ OPTION_BUFFER_SIZE, "BufferSize", OPTV_INTEGER, {0}, FALSE },
{ OPTION_DEPTH_MOVE, "EnableDepthMoves", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PAGE_FLIP, "EnablePageFlip", OPTV_BOOLEAN, {0}, FALSE },
#endif
{ OPTION_CRT_SCREEN, "CrtScreen", OPTV_BOOLEAN, {0}, FALSE},
{ OPTION_PANEL_SIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE },
@@ -290,6 +292,11 @@ static const char *driSymbols[] = {
"GlxSetVisualConfigs",
NULL
};
+
+static const char *driShadowSymbols[] = {
+ "shadowInit",
+ NULL
+};
#endif
static const char *vbeSymbols[] = {
@@ -1977,6 +1984,24 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn)
"Depth moves disabled by default\n");
}
+
+ if (!xf86LoadSubModule(pScrn, "shadow")) {
+ info->allowPageFlip = 0;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling page flipping\n");
+ }
+ else {
+ xf86LoaderReqSymLists(driShadowSymbols, NULL);
+
+ if ((info->allowPageFlip = xf86ReturnOptValBool(info->Options,
+ OPTION_PAGE_FLIP,
+ FALSE))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page flipping enabled\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Disabling page flipping\n");
+ }
+ }
+
+
return TRUE;
}
#endif
@@ -2634,7 +2659,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
* pixmap cache. Should be enough for a fullscreen background
* image plus some leftovers.
*/
- info->textureSize = info->FbMapSize - 6 * bufferSize;
+ info->textureSize = info->FbMapSize - 4 * bufferSize;
/* If that gives us less than half the available memory, let's
* be greedy and grab some more. Sorry, I care more about 3D
@@ -2698,6 +2723,9 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
scanlines = info->backOffset / width_bytes - 1;
if (scanlines > 8191) scanlines = 8191;
+ info->backY = scanlines;
+ info->backX = (info->backOffset - (scanlines * width_bytes - 1)) / cpp;
+
MemBox.x1 = 0;
MemBox.y1 = 0;
MemBox.x2 = pScrn->displayWidth;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h
index c447364e4..1d56204e9 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h
@@ -327,7 +327,6 @@
#define RADEON_CRC_CMDFIFO_ADDR 0x0740
#define RADEON_CRC_CMDFIFO_DOUT 0x0744
#define RADEON_CRTC_CRNT_FRAME 0x0214
-#define RADEON_CRTC_DEBUG 0x021c
#define RADEON_CRTC_EXT_CNTL 0x0054
# define RADEON_CRTC_VGA_XOVERSCAN (1 << 0)
# define RADEON_VGA_ATI_LINEAR (1 << 3)
@@ -426,7 +425,6 @@
#define RADEON_CRTC_VLINE_CRNT_VLINE 0x0210
# define RADEON_CRTC_CRNT_VLINE_MASK (0x7ff << 16)
#define RADEON_CRTC2_CRNT_FRAME 0x0314
-#define RADEON_CRTC2_DEBUG 0x031c
#define RADEON_CRTC2_GUI_TRIG_VLINE 0x0318
#define RADEON_CRTC2_STATUS 0x03fc
#define RADEON_CRTC2_VLINE_CRNT_VLINE 0x0310
@@ -739,13 +737,6 @@
#define RADEON_GRPH8_DATA 0x03cf /* VGA */
#define RADEON_GRPH8_IDX 0x03ce /* VGA */
-#define RADEON_GUI_DEBUG0 0x16a0
-#define RADEON_GUI_DEBUG1 0x16a4
-#define RADEON_GUI_DEBUG2 0x16a8
-#define RADEON_GUI_DEBUG3 0x16ac
-#define RADEON_GUI_DEBUG4 0x16b0
-#define RADEON_GUI_DEBUG5 0x16b4
-#define RADEON_GUI_DEBUG6 0x16b8
#define RADEON_GUI_SCRATCH_REG0 0x15e0
#define RADEON_GUI_SCRATCH_REG1 0x15e4
#define RADEON_GUI_SCRATCH_REG2 0x15e8
@@ -766,8 +757,6 @@
# define RADEON_HDP_SOFT_RESET (1 << 26)
#define RADEON_HTOTAL_CNTL 0x0009 /* PLL */
#define RADEON_HTOTAL2_CNTL 0x002e /* PLL */
-#define RADEON_HW_DEBUG 0x0128
-#define RADEON_HW_DEBUG2 0x011c
#define RADEON_I2C_CNTL_1 0x0094 /* ? */
#define RADEON_DVI_I2C_CNTL_1 0x02e4 /* ? */
@@ -1065,9 +1054,6 @@
#define RADEON_SURFACE7_UPPER_BOUND 0x0b78
#define RADEON_SW_SEMAPHORE 0x013c
-#define RADEON_TEST_DEBUG_CNTL 0x0120
-#define RADEON_TEST_DEBUG_MUX 0x0124
-#define RADEON_TEST_DEBUG_OUT 0x012c
#define RADEON_TMDS_CRC 0x02a0
#define RADEON_TRAIL_BRES_DEC 0x1614
#define RADEON_TRAIL_BRES_ERR 0x160c
@@ -1191,7 +1177,7 @@
# define RADEON_MAX_ANISO_8_TO_1 (3 << 5)
# define RADEON_MAX_ANISO_16_TO_1 (4 << 5)
# define RADEON_MAX_ANISO_MASK (7 << 5)
-# define RADEON_LOD_BIAS_MASK (0xffff << 8)
+# define RADEON_LOD_BIAS_MASK (0xff << 8)
# define RADEON_LOD_BIAS_SHIFT 8
# define RADEON_MAX_MIP_LEVEL_MASK (0x0f << 16)
# define RADEON_MAX_MIP_LEVEL_SHIFT 16
@@ -1438,8 +1424,6 @@
# define RADEON_COLOR_FORMAT_aYUV444 (14 << 10)
# define RADEON_COLOR_FORMAT_ARGB4444 (15 << 10)
# define RADEON_CLRCMP_FLIP_ENABLE (1 << 14)
-# define RADEON_ZBLOCK8 (0 << 15)
-# define RADEON_ZBLOCK16 (1 << 15)
#define RADEON_RB3D_COLOROFFSET 0x1c40
# define RADEON_COLOROFFSET_MASK 0xfffffff0
#define RADEON_RB3D_COLORPITCH 0x1c48
@@ -1500,7 +1484,6 @@
# define RADEON_Z_TEST_NEQUAL (6 << 4)
# define RADEON_Z_TEST_ALWAYS (7 << 4)
# define RADEON_Z_TEST_MASK (7 << 4)
-# define RADEON_HIERARCHICAL_Z_ENABLE (1 << 8)
# define RADEON_STENCIL_TEST_NEVER (0 << 12)
# define RADEON_STENCIL_TEST_LESS (1 << 12)
# define RADEON_STENCIL_TEST_LEQUAL (2 << 12)
@@ -1531,10 +1514,7 @@
# define RADEON_STENCIL_ZFAIL_DEC (4 << 24)
# define RADEON_STENCIL_ZFAIL_INVERT (5 << 24)
# define RADEON_STENCIL_ZFAIL_MASK (0x7 << 24)
-# define RADEON_Z_COMPRESSION_ENABLE (1 << 28)
-# define RADEON_FORCE_Z_DIRTY (1 << 29)
# define RADEON_Z_WRITE_ENABLE (1 << 30)
-# define RADEON_Z_DECOMPRESSION_ENABLE (1 << 31)
#define RADEON_RE_LINE_PATTERN 0x1cd0
# define RADEON_LINE_PATTERN_MASK 0x0000ffff
# define RADEON_LINE_REPEAT_COUNT_SHIFT 16
@@ -1613,7 +1593,7 @@
# define RADEON_VC_32BIT_SWAP (2 << 0)
# define RADEON_VC_HALF_DWORD_SWAP (3 << 0)
# define RADEON_TCL_BYPASS (1 << 8)
-#define RADEON_SE_COORD_FMT 0x15c0
+#define RADEON_SE_COORD_FMT 0x1c50
# define RADEON_VTX_XY_PRE_MULT_1_OVER_W0 (1 << 0)
# define RADEON_VTX_Z_PRE_MULT_1_OVER_W0 (1 << 1)
# define RADEON_VTX_ST0_NONPARAMETRIC (1 << 8)
@@ -1629,7 +1609,6 @@
# define RADEON_TEX1_W_ROUTING_USE_W0 (0 << 26)
# define RADEON_TEX1_W_ROUTING_USE_Q1 (1 << 26)
#define RADEON_SE_LINE_WIDTH 0x1db8
-#define RADEON_SE_TCL_LIGHT_MODEL_CTL 0x226c
#define RADEON_SE_TCL_MATERIAL_AMBIENT_RED 0x2220
#define RADEON_SE_TCL_MATERIAL_AMBIENT_GREEN 0x2224
#define RADEON_SE_TCL_MATERIAL_AMBIENT_BLUE 0x2228
@@ -1646,17 +1625,185 @@
#define RADEON_SE_TCL_MATERIAL_SPECULAR_GREEN 0x2244
#define RADEON_SE_TCL_MATERIAL_SPECULAR_BLUE 0x2248
#define RADEON_SE_TCL_MATERIAL_SPECULAR_ALPHA 0x224c
-#define RADEON_SE_TCL_MATRIX_SELECT_0 0x225c
-#define RADEON_SE_TCL_MATRIX_SELECT_1 0x2260
+#define RADEON_SE_TCL_SHININESS 0x2250
+
#define RADEON_SE_TCL_OUTPUT_VTX_FMT 0x2254
+#define RADEON_TCL_VTX_W0 (1<<0)
+#define RADEON_TCL_VTX_FP_DIFFUSE (1<<1)
+#define RADEON_TCL_VTX_FP_ALPHA (1<<2)
+#define RADEON_TCL_VTX_PK_DIFFUSE (1<<3)
+#define RADEON_TCL_VTX_FP_SPEC (1<<4)
+#define RADEON_TCL_VTX_FP_FOG (1<<5)
+#define RADEON_TCL_VTX_PK_SPEC (1<<6)
+#define RADEON_TCL_VTX_ST0 (1<<7)
+#define RADEON_TCL_VTX_ST1 (1<<8)
+#define RADEON_TCL_VTX_Q1 (1<<9)
+#define RADEON_TCL_VTX_ST2 (1<<10)
+#define RADEON_TCL_VTX_Q2 (1<<11)
+#define RADEON_TCL_VTX_ST3 (1<<12)
+#define RADEON_TCL_VTX_Q3 (1<<13)
+#define RADEON_TCL_VTX_Q0 (1<<14)
+#define RADEON_TCL_VTX_WEIGHT_COUNT_SHIFT (15)
+#define RADEON_TCL_VTX_NORM0 (1<<18)
+#define RADEON_TCL_VTX_XY1 (1<<27)
+#define RADEON_TCL_VTX_Z1 (1<<28)
+#define RADEON_TCL_VTX_W1 (1<<29)
+#define RADEON_TCL_VTX_NORM1 (1<<30)
+#define RADEON_TCL_VTX_Z0 (1<<31)
+
+
#define RADEON_SE_TCL_OUTPUT_VTX_SEL 0x2258
+#define RADEON_TCL_COMPUTE_XYZW (1<<0)
+#define RADEON_TCL_COMPUTE_DIFFUSE (1<<1)
+#define RADEON_TCL_COMPUTE_SPECULAR (1<<2)
+#define RADEON_TCL_FORCE_NAN_IF_COLOR_NAN (1<<3)
+#define RADEON_TCL_FORCE_INORDER_PROC (1<<4)
+#define RADEON_TCL_TEX_INPUT_TEX_0 (0)
+#define RADEON_TCL_TEX_INPUT_TEX_1 (1)
+#define RADEON_TCL_TEX_INPUT_TEX_2 (2)
+#define RADEON_TCL_TEX_INPUT_TEX_3 (3)
+#define RADEON_TCL_TEX_COMPUTED_TEX_0 (8)
+#define RADEON_TCL_TEX_COMPUTED_TEX_1 (9)
+#define RADEON_TCL_TEX_COMPUTED_TEX_2 (10)
+#define RADEON_TCL_TEX_COMPUTED_TEX_3 (11)
+#define RADEON_TCL_TEX_0_OUTPUT_SHIFT (16)
+#define RADEON_TCL_TEX_1_OUTPUT_SHIFT (20)
+#define RADEON_TCL_TEX_2_OUTPUT_SHIFT (24)
+#define RADEON_TCL_TEX_3_OUTPUT_SHIFT (28)
+
+#define RADEON_SE_TCL_MATRIX_SELECT_0 0x225c
+#define RADEON_MODELVIEW_0_SHIFT (0)
+#define RADEON_MODELVIEW_1_SHIFT (4)
+#define RADEON_MODELVIEW_2_SHIFT (8)
+#define RADEON_MODELVIEW_3_SHIFT (12)
+#define RADEON_IT_MODELVIEW_0_SHIFT (16)
+#define RADEON_IT_MODELVIEW_1_SHIFT (20)
+#define RADEON_IT_MODELVIEW_2_SHIFT (24)
+#define RADEON_IT_MODELVIEW_3_SHIFT (28)
+
+#define RADEON_SE_TCL_MATRIX_SELECT_1 0x2260
+#define RADEON_MODELPROJECT_0_SHIFT (0)
+#define RADEON_MODELPROJECT_1_SHIFT (4)
+#define RADEON_MODELPROJECT_2_SHIFT (8)
+#define RADEON_MODELPROJECT_3_SHIFT (12)
+#define RADEON_TEXMAT_0_SHIFT (16)
+#define RADEON_TEXMAT_1_SHIFT (20)
+#define RADEON_TEXMAT_2_SHIFT (24)
+#define RADEON_TEXMAT_3_SHIFT (28)
+
+#define RADEON_SE_TCL_UCP_VERT_BLEND_CTL 0x2264
+#define RADEON_UCP_IN_CLIP_SPACE (1<<0)
+#define RADEON_UCP_IN_MODEL_SPACE (1<<1)
+#define RADEON_UCP_ENABLE_0 (1<<2)
+#define RADEON_UCP_ENABLE_1 (1<<3)
+#define RADEON_UCP_ENABLE_2 (1<<4)
+#define RADEON_UCP_ENABLE_3 (1<<5)
+#define RADEON_UCP_ENABLE_4 (1<<6)
+#define RADEON_UCP_ENABLE_5 (1<<7)
+#define RADEON_TCL_FOG_MASK (3<<8)
+#define RADEON_TCL_FOG_DISABLE (0<<8)
+#define RADEON_TCL_FOG_EXP (1<<8)
+#define RADEON_TCL_FOG_EXP2 (2<<8)
+#define RADEON_TCL_FOG_LINEAR (3<<8)
+#define RADEON_RNG_BASED_FOG (1<<10)
+#define RADEON_LIGHT_TWOSIDE (1<<11)
+#define RADEON_BLEND_OP_COUNT_MASK (7<<12)
+#define RADEON_BLEND_OP_COUNT_SHIFT (12)
+#define RADEON_POSITION_BLEND_OP_ENABLE (1<<16)
+#define RADEON_NORMAL_BLEND_OP_ENABLE (1<<17)
+#define RADEON_VERTEX_BLEND_SRC_0_PRIMARY (1<<18)
+#define RADEON_VERTEX_BLEND_SRC_0_SECONDARY (1<<18)
+#define RADEON_VERTEX_BLEND_SRC_1_PRIMARY (1<<19)
+#define RADEON_VERTEX_BLEND_SRC_1_SECONDARY (1<<19)
+#define RADEON_VERTEX_BLEND_SRC_2_PRIMARY (1<<20)
+#define RADEON_VERTEX_BLEND_SRC_2_SECONDARY (1<<20)
+#define RADEON_VERTEX_BLEND_SRC_3_PRIMARY (1<<21)
+#define RADEON_VERTEX_BLEND_SRC_3_SECONDARY (1<<21)
+#define RADEON_VERTEX_BLEND_WGT_MINUS_ONE (1<<22)
+#define RADEON_CULL_FRONT_IS_CW (0<<28)
+#define RADEON_CULL_FRONT_IS_CCW (1<<28)
+#define RADEON_CULL_FRONT (1<<29)
+#define RADEON_CULL_BACK (1<<30)
+#define RADEON_FORCE_W_TO_ONE (1<<31)
+
+#define RADEON_SE_TCL_TEXTURE_PROC_CTL 0x2268
+#define RADEON_TEXGEN_TEXMAT_0_ENABLE (1<<0)
+#define RADEON_TEXGEN_TEXMAT_1_ENABLE (1<<1)
+#define RADEON_TEXGEN_TEXMAT_2_ENABLE (1<<2)
+#define RADEON_TEXGEN_TEXMAT_3_ENABLE (1<<3)
+#define RADEON_TEXMAT_0_ENABLE (1<<4)
+#define RADEON_TEXMAT_1_ENABLE (1<<5)
+#define RADEON_TEXMAT_2_ENABLE (1<<6)
+#define RADEON_TEXMAT_3_ENABLE (1<<7)
+#define RADEON_TEXGEN_INPUT_MASK (0xf)
+#define RADEON_TEXGEN_INPUT_TEXCOORD_0 (0)
+#define RADEON_TEXGEN_INPUT_TEXCOORD_1 (1)
+#define RADEON_TEXGEN_INPUT_TEXCOORD_2 (2)
+#define RADEON_TEXGEN_INPUT_TEXCOORD_3 (3)
+#define RADEON_TEXGEN_INPUT_OBJ (4)
+#define RADEON_TEXGEN_INPUT_EYE (5)
+#define RADEON_TEXGEN_INPUT_EYE_NORMAL (6)
+#define RADEON_TEXGEN_INPUT_EYE_REFLECT (7)
+#define RADEON_TEXGEN_INPUT_EYE_NORMALIZED (8)
+#define RADEON_TEXGEN_0_INPUT_SHIFT (16)
+#define RADEON_TEXGEN_1_INPUT_SHIFT (20)
+#define RADEON_TEXGEN_2_INPUT_SHIFT (24)
+#define RADEON_TEXGEN_3_INPUT_SHIFT (28)
+
+
+#define RADEON_SE_TCL_LIGHT_MODEL_CTL 0x226c
+#define RADEON_LIGHTING_ENABLE (1<<0)
+#define RADEON_LIGHT_IN_MODELSPACE (1<<1)
+#define RADEON_LOCAL_VIEWER (1<<2)
+#define RADEON_NORMALIZE_NORMALS (1<<3)
+#define RADEON_RESCALE_NORMALS (1<<4)
+#define RADEON_SPECULAR_LIGHTS (1<<5)
+#define RADEON_DIFFUSE_SPECULAR_COMBINE (1<<6)
+#define RADEON_LIGHT_ALPHA (1<<7)
+#define RADEON_LOCAL_LIGHT_VEC_GL (1<<8)
+#define RADEON_LIGHT_NO_NORMAL_AMBIENT_ONLY (1<<9)
+#define RADEON_LM_SOURCE_STATE_PREMULT (0)
+#define RADEON_LM_SOURCE_STATE_MULT (1)
+#define RADEON_LM_SOURCE_VERTEX_DIFFUSE (2)
+#define RADEON_LM_SOURCE_VERTEX_SPECULAR (3)
+#define RADEON_EMISSIVE_SOURCE_SHIFT (16)
+#define RADEON_AMBIENT_SOURCE_SHIFT (18)
+#define RADEON_DIFFUSE_SOURCE_SHIFT (20)
+#define RADEON_SPECULAR_SOURCE_SHIFT (22)
+
+
#define RADEON_SE_TCL_PER_LIGHT_CTL_0 0x2270
+#define RADEON_LIGHT_0_SHIFT (0)
+#define RADEON_LIGHT_1_SHIFT (16)
#define RADEON_SE_TCL_PER_LIGHT_CTL_1 0x2274
+#define RADEON_LIGHT_2_SHIFT (0)
+#define RADEON_LIGHT_3_SHIFT (16)
#define RADEON_SE_TCL_PER_LIGHT_CTL_2 0x2278
+#define RADEON_LIGHT_4_SHIFT (0)
+#define RADEON_LIGHT_5_SHIFT (16)
#define RADEON_SE_TCL_PER_LIGHT_CTL_3 0x227c
-#define RADEON_SE_TCL_SHININESS 0x2250
-#define RADEON_SE_TCL_TEXTURE_PROC_CTL 0x2268
-#define RADEON_SE_TCL_UCP_VERT_BLEND_CTL 0x2264
+#define RADEON_LIGHT_6_SHIFT (0)
+#define RADEON_LIGHT_7_SHIFT (16)
+
+#define RADEON_LIGHT_0_ENABLE (1<<0)
+#define RADEON_LIGHT_0_ENABLE_AMBIENT (1<<1)
+#define RADEON_LIGHT_0_ENABLE_SPECULAR (1<<2)
+#define RADEON_LIGHT_0_IS_LOCAL (1<<3)
+#define RADEON_LIGHT_0_IS_SPOT (1<<4)
+#define RADEON_LIGHT_0_DUAL_CONE (1<<5)
+#define RADEON_LIGHT_0_ENABLE_RANGE_ATTEN (1<<6)
+#define RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN (1<<7)
+
+#define RADEON_LIGHT_1_ENABLE (1<<16)
+#define RADEON_LIGHT_1_ENABLE_AMBIENT (1<<17)
+#define RADEON_LIGHT_1_ENABLE_SPECULAR (1<<18)
+#define RADEON_LIGHT_1_IS_LOCAL (1<<19)
+#define RADEON_LIGHT_1_IS_SPOT (1<<20)
+#define RADEON_LIGHT_1_DUAL_CONE (1<<21)
+#define RADEON_LIGHT_1_ENABLE_RANGE_ATTEN (1<<22)
+#define RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN (1<<23)
+
+
#define RADEON_SE_VPORT_XSCALE 0x1d98
#define RADEON_SE_VPORT_XOFFSET 0x1d9c
#define RADEON_SE_VPORT_YSCALE 0x1da0
@@ -1732,14 +1879,12 @@
#define RADEON_CP_PACKET3_SET_SCISSORS 0xC0001E00
#define RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300
#define RADEON_CP_PACKET3_LOAD_MICROCODE 0xC0002400
-#define RADEON_CP_PACKET3_3D_RNDR_GEN_PRIM 0xC0002500
#define RADEON_CP_PACKET3_WAIT_FOR_IDLE 0xC0002600
#define RADEON_CP_PACKET3_3D_DRAW_VBUF 0xC0002800
#define RADEON_CP_PACKET3_3D_DRAW_IMMD 0xC0002900
#define RADEON_CP_PACKET3_3D_DRAW_INDX 0xC0002A00
#define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00
#define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00
-#define RADEON_CP_PACKET3_3D_CLEAR_ZMASK 0xC0003200
#define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100
#define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200
#define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300
@@ -1794,7 +1939,48 @@
#define RADEON_CP_VC_CNTL_MAOS_ENABLE 0x00000080
#define RADEON_CP_VC_CNTL_VTX_FMT_NON_RADEON_MODE 0x00000000
#define RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE 0x00000100
+#define RADEON_CP_VC_CNTL_TCL_DISABLE 0x00000000
+#define RADEON_CP_VC_CNTL_TCL_ENABLE 0x00000200
#define RADEON_CP_VC_CNTL_NUM_SHIFT 16
+#define RADEON_VS_MATRIX_0_ADDR 0
+#define RADEON_VS_MATRIX_1_ADDR 4
+#define RADEON_VS_MATRIX_2_ADDR 8
+#define RADEON_VS_MATRIX_3_ADDR 12
+#define RADEON_VS_MATRIX_4_ADDR 16
+#define RADEON_VS_MATRIX_5_ADDR 20
+#define RADEON_VS_MATRIX_6_ADDR 24
+#define RADEON_VS_MATRIX_7_ADDR 28
+#define RADEON_VS_MATRIX_8_ADDR 32
+#define RADEON_VS_MATRIX_9_ADDR 36
+#define RADEON_VS_MATRIX_10_ADDR 40
+#define RADEON_VS_MATRIX_11_ADDR 44
+#define RADEON_VS_MATRIX_12_ADDR 48
+#define RADEON_VS_MATRIX_13_ADDR 52
+#define RADEON_VS_MATRIX_14_ADDR 56
+#define RADEON_VS_MATRIX_15_ADDR 60
+#define RADEON_VS_LIGHT_AMBIENT_ADDR 64
+#define RADEON_VS_LIGHT_DIFFUSE_ADDR 72
+#define RADEON_VS_LIGHT_SPECULAR_ADDR 80
+#define RADEON_VS_LIGHT_DIRPOS_ADDR 88
+#define RADEON_VS_LIGHT_HWVSPOT_ADDR 96
+#define RADEON_VS_LIGHT_ATTENUATION_ADDR 104
+#define RADEON_VS_MATRIX_EYE2CLIP_ADDR 112
+#define RADEON_VS_UCP_ADDR 116
+#define RADEON_VS_GLOBAL_AMBIENT_ADDR 122
+#define RADEON_VS_FOG_PARAM_ADDR 123
+#define RADEON_VS_EYE_VECTOR_ADDR 124
+
+#define RADEON_SS_LIGHT_DCD_ADDR 0
+#define RADEON_SS_LIGHT_SPOT_EXPONENT_ADDR 8
+#define RADEON_SS_LIGHT_SPOT_CUTOFF_ADDR 16
+#define RADEON_SS_LIGHT_SPECULAR_THRESH_ADDR 24
+#define RADEON_SS_LIGHT_RANGE_CUTOFF_ADDR 32
+#define RADEON_SS_VERT_GUARD_CLIP_ADJ_ADDR 48
+#define RADEON_SS_VERT_GUARD_DISCARD_ADJ_ADDR 49
+#define RADEON_SS_HORZ_GUARD_CLIP_ADJ_ADDR 50
+#define RADEON_SS_HORZ_GUARD_DISCARD_ADJ_ADDR 51
+#define RADEON_SS_SHININESS 60
+
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h
index cdcdd5fa9..2f93e6be9 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h
@@ -173,23 +173,6 @@ typedef struct {
/* Setup state */
unsigned int se_cntl_status;
-#ifdef TCL_ENABLE
- /* TCL state */
- radeon_color_regs_t se_tcl_material_emmissive;
- radeon_color_regs_t se_tcl_material_ambient;
- radeon_color_regs_t se_tcl_material_diffuse;
- radeon_color_regs_t se_tcl_material_specular;
- unsigned int se_tcl_shininess;
- unsigned int se_tcl_output_vtx_fmt;
- unsigned int se_tcl_output_vtx_sel;
- unsigned int se_tcl_matrix_select_0;
- unsigned int se_tcl_matrix_select_1;
- unsigned int se_tcl_ucp_vert_blend_ctl;
- unsigned int se_tcl_texture_proc_ctl;
- unsigned int se_tcl_light_model_ctl;
- unsigned int se_tcl_per_light_ctl[4];
-#endif
-
/* Misc state */
unsigned int re_top_left;
unsigned int re_misc;
@@ -203,13 +186,7 @@ typedef struct {
unsigned int pp_txcblend;
unsigned int pp_txablend;
unsigned int pp_tfactor;
-
unsigned int pp_border_color;
-
-#ifdef CUBIC_ENABLE
- unsigned int pp_cubic_faces;
- unsigned int pp_cubic_offset[5];
-#endif
} radeon_texture_regs_t;
typedef struct {
@@ -259,6 +236,8 @@ typedef struct {
int texAge[RADEON_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 */
} RADEONSAREAPriv, *RADEONSAREAPrivPtr;
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Imakefile
index cf6ba5724..cacdc7a11 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Imakefile
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Imakefile
@@ -17,3 +17,4 @@ all::
clean::
$(MAKE) -f Makefile.linux clean
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
index d116f3752..6ab295c48 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
@@ -84,6 +84,10 @@ typedef unsigned int drm_magic_t;
/* Warning: If you change this structure, make sure you change
* XF86DRIClipRectRec in the server as well */
+/* KW: Actually it's illegal to change either for
+ * backwards-compatibility reasons.
+ */
+
typedef struct drm_clip_rect {
unsigned short x1;
unsigned short y1;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c
index 14901f59c..5486f1c13 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c
@@ -461,6 +461,7 @@ int radeon_do_cp_idle( drm_radeon_private_t *dev_priv )
RADEON_WAIT_UNTIL_IDLE();
ADVANCE_RING();
+ COMMIT_RING();
return radeon_do_wait_for_idle( dev_priv );
}
@@ -485,6 +486,7 @@ static void radeon_do_cp_start( drm_radeon_private_t *dev_priv )
RADEON_WAIT_UNTIL_IDLE();
ADVANCE_RING();
+ COMMIT_RING();
}
/* Reset the Command Processor. This will not flush any pending
@@ -751,7 +753,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
*/
dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE |
(dev_priv->color_fmt << 10) |
- RADEON_ZBLOCK16);
+ (1<<15));
dev_priv->depth_clear.rb3d_zstencilcntl =
(dev_priv->depth_fmt |
@@ -970,9 +972,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
radeon_cp_load_microcode( dev_priv );
radeon_cp_init_ring_buffer( dev, dev_priv );
-#if ROTATE_BUFS
dev_priv->last_buf = 0;
-#endif
dev->dev_private = (void *)dev_priv;
@@ -1152,116 +1152,27 @@ int radeon_engine_reset( struct inode *inode, struct file *filp,
* Fullscreen mode
*/
-static int radeon_do_init_pageflip( drm_device_t *dev )
-{
- drm_radeon_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
-
- dev_priv->crtc_offset = RADEON_READ( RADEON_CRTC_OFFSET );
- dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL );
-
- RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->front_offset );
- RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL,
- dev_priv->crtc_offset_cntl |
- RADEON_CRTC_OFFSET_FLIP_CNTL );
-
- dev_priv->page_flipping = 1;
- dev_priv->current_page = 0;
-
- return 0;
-}
-
-int radeon_do_cleanup_pageflip( drm_device_t *dev )
-{
- drm_radeon_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
-
- RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->crtc_offset );
- RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
-
- dev_priv->page_flipping = 0;
- dev_priv->current_page = 0;
-
- return 0;
-}
-
+/* KW: Deprecated to say the least:
+ */
int radeon_fullscreen( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_radeon_fullscreen_t fs;
-
- LOCK_TEST_WITH_RETURN( dev );
-
- if ( copy_from_user( &fs, (drm_radeon_fullscreen_t *)arg,
- sizeof(fs) ) )
- return -EFAULT;
-
- switch ( fs.func ) {
- case RADEON_INIT_FULLSCREEN:
- return radeon_do_init_pageflip( dev );
- case RADEON_CLEANUP_FULLSCREEN:
- return radeon_do_cleanup_pageflip( dev );
- }
-
- return -EINVAL;
+ return 0;
}
/* ================================================================
* Freelist management
*/
-#define RADEON_BUFFER_USED 0xffffffff
-#define RADEON_BUFFER_FREE 0
-
-#if 0
-static int radeon_freelist_init( drm_device_t *dev )
-{
- drm_device_dma_t *dma = dev->dma;
- drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_buf_t *buf;
- drm_radeon_buf_priv_t *buf_priv;
- drm_radeon_freelist_t *entry;
- int i;
-
- dev_priv->head = DRM(alloc)( sizeof(drm_radeon_freelist_t),
- DRM_MEM_DRIVER );
- if ( dev_priv->head == NULL )
- return -ENOMEM;
-
- memset( dev_priv->head, 0, sizeof(drm_radeon_freelist_t) );
- dev_priv->head->age = RADEON_BUFFER_USED;
-
- for ( i = 0 ; i < dma->buf_count ; i++ ) {
- buf = dma->buflist[i];
- buf_priv = buf->dev_private;
-
- entry = DRM(alloc)( sizeof(drm_radeon_freelist_t),
- DRM_MEM_DRIVER );
- if ( !entry ) return -ENOMEM;
-
- entry->age = RADEON_BUFFER_FREE;
- entry->buf = buf;
- entry->prev = dev_priv->head;
- entry->next = dev_priv->head->next;
- if ( !entry->next )
- dev_priv->tail = entry;
- buf_priv->discard = 0;
- buf_priv->dispatched = 0;
- buf_priv->list_entry = entry;
-
- dev_priv->head->next = entry;
-
- if ( dev_priv->head->next )
- dev_priv->head->next->prev = entry;
- }
-
- return 0;
-
-}
-#endif
+/* Original comment: FIXME: ROTATE_BUFS is a hack to cycle through
+ * bufs until freelist code is used. Note this hides a problem with
+ * the scratch register * (used to keep track of last buffer
+ * completed) being written to before * the last buffer has actually
+ * completed rendering.
+ *
+ * KW: It's also a good way to find free buffers quickly.
+ */
drm_buf_t *radeon_freelist_get( drm_device_t *dev )
{
@@ -1270,57 +1181,24 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev )
drm_radeon_buf_priv_t *buf_priv;
drm_buf_t *buf;
int i, t;
-#if ROTATE_BUFS
int start;
-#endif
-
- /* FIXME: Optimize -- use freelist code */
- for ( i = 0 ; i < dma->buf_count ; i++ ) {
- buf = dma->buflist[i];
- buf_priv = buf->dev_private;
- if ( buf->pid == 0 ) {
- DRM_DEBUG( " ret buf=%d last=%d pid=0\n",
- buf->idx, dev_priv->last_buf );
- return buf;
- }
- DRM_DEBUG( " skipping buf=%d pid=%d\n",
- buf->idx, buf->pid );
- }
-
-#if ROTATE_BUFS
if ( ++dev_priv->last_buf >= dma->buf_count )
dev_priv->last_buf = 0;
+
start = dev_priv->last_buf;
-#endif
+
for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) {
-#if 0
- /* FIXME: Disable this for now */
- u32 done_age = dev_priv->scratch[RADEON_LAST_DISPATCH];
-#else
u32 done_age = RADEON_READ( RADEON_LAST_DISPATCH_REG );
-#endif
-#if ROTATE_BUFS
for ( i = start ; i < dma->buf_count ; i++ ) {
-#else
- for ( i = 0 ; i < dma->buf_count ; i++ ) {
-#endif
buf = dma->buflist[i];
buf_priv = buf->dev_private;
- if ( buf->pending && buf_priv->age <= done_age ) {
- /* The buffer has been processed, so it
- * can now be used.
- */
+ if ( buf->pid == 0 || (buf->pending &&
+ buf_priv->age <= done_age) ) {
buf->pending = 0;
- DRM_DEBUG( " ret buf=%d last=%d age=%d done=%d\n", buf->idx, dev_priv->last_buf, buf_priv->age, done_age );
return buf;
}
- DRM_DEBUG( " skipping buf=%d age=%d done=%d\n",
- buf->idx, buf_priv->age,
- done_age );
-#if ROTATE_BUFS
start = 0;
-#endif
}
udelay( 1 );
}
@@ -1332,14 +1210,10 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev )
void radeon_freelist_reset( drm_device_t *dev )
{
drm_device_dma_t *dma = dev->dma;
-#if ROTATE_BUFS
drm_radeon_private_t *dev_priv = dev->dev_private;
-#endif
int i;
-#if ROTATE_BUFS
dev_priv->last_buf = 0;
-#endif
for ( i = 0 ; i < dma->buf_count ; i++ ) {
drm_buf_t *buf = dma->buflist[i];
drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h
index 6774b2bc0..dd24d4299 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h
@@ -2,6 +2,7 @@
*
* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
* 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
@@ -38,7 +39,8 @@
#ifndef __RADEON_SAREA_DEFINES__
#define __RADEON_SAREA_DEFINES__
-/* What needs to be changed for the current vertex buffer?
+/* Old style state flags, required for sarea interface (1.1 and 1.2
+ * clears) and 1.2 drm_vertex2 ioctl.
*/
#define RADEON_UPLOAD_CONTEXT 0x00000001
#define RADEON_UPLOAD_VERTFMT 0x00000002
@@ -58,8 +60,68 @@
#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */
#define RADEON_REQUIRE_QUIESCENCE 0x00010000
#define RADEON_UPLOAD_ZBIAS 0x00020000 /* version 1.2 and newer */
-#define RADEON_UPLOAD_ALL 0x0002ffff
-#define RADEON_UPLOAD_CONTEXT_ALL 0x000201ff
+#define RADEON_UPLOAD_ALL 0x003effff
+#define RADEON_UPLOAD_CONTEXT_ALL 0x003e01ff
+
+
+/* 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 RADEON_MAX_STATE_PACKETS 21
+
+
+/* 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 */
+
+
+typedef union {
+ int i;
+ struct {
+ char cmd_type, pad0, pad1, pad2;
+ } header;
+ struct {
+ char cmd_type, packet_id, pad0, pad1;
+ } packet;
+ struct {
+ char cmd_type, offset, stride, count;
+ } scalars;
+ struct {
+ char cmd_type, offset, stride, count;
+ } vectors;
+ struct {
+ char cmd_type, buf_idx, pad0, pad1;
+ } dma;
+} drm_radeon_cmd_header_t;
+
#define RADEON_FRONT 0x1
#define RADEON_BACK 0x2
@@ -82,7 +144,6 @@
/* Byte offsets for indirect buffer data
*/
#define RADEON_INDEX_PRIM_OFFSET 20
-#define RADEON_HOSTDATA_BLIT_OFFSET 32
#define RADEON_SCRATCH_REG_OFFSET 32
@@ -181,8 +242,6 @@ typedef struct {
unsigned int pp_border_color;
} drm_radeon_texture_regs_t;
-/* Space is crucial; there is some redunancy here:
- */
typedef struct {
unsigned int start;
unsigned int finish;
@@ -192,6 +251,7 @@ typedef struct {
unsigned int vc_format; /* vertex format */
} drm_radeon_prim_t;
+
typedef struct {
drm_radeon_context_regs_t context;
drm_radeon_texture_regs_t tex[RADEON_MAX_TEXTURE_UNITS];
@@ -231,6 +291,8 @@ typedef struct {
drm_radeon_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1];
int tex_age[RADEON_NR_TEX_HEAPS];
int ctx_owner;
+ int pfState; /* number of 3d windows (0,1,2ormore) */
+ int pfCurrentPage; /* which buffer is being displayed? */
} drm_radeon_sarea_t;
@@ -258,6 +320,9 @@ typedef struct {
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t)
#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex_t)
+#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t)
+#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t)
+#define DRM_IOCTL_RADEON_FLIP DRM_IO( 0x52)
typedef struct drm_radeon_init {
enum {
@@ -324,6 +389,18 @@ typedef struct drm_radeon_vertex {
int discard; /* Client finished with buffer? */
} drm_radeon_vertex_t;
+typedef struct drm_radeon_indices {
+ int prim;
+ int idx;
+ int start;
+ int end;
+ int discard; /* Client finished with buffer? */
+} drm_radeon_indices_t;
+
+/* v1.2 - obsoletes drm_radeon_vertex and drm_radeon_indices
+ * - allows multiple primitives and state changes in a single ioctl
+ * - supports driver change to emit native primitives
+ */
typedef struct drm_radeon_vertex2 {
int idx; /* Index of vertex buffer */
int discard; /* Client finished with buffer? */
@@ -333,13 +410,22 @@ typedef struct drm_radeon_vertex2 {
drm_radeon_prim_t *prim;
} drm_radeon_vertex2_t;
-typedef struct drm_radeon_indices {
- int prim;
- int idx;
- int start;
- int end;
- int discard; /* Client finished with buffer? */
-} drm_radeon_indices_t;
+/* v1.3 - obsoletes drm_radeon_vertex2
+ * - allows arbitarily large cliprect list
+ * - allows updating of tcl packet, vector and scalar state
+ * - allows memory-efficient description of state updates
+ * - allows state to be emitted without a primitive
+ * (for clears, ctx switches)
+ * - allows more than one dma buffer to be referenced per ioctl
+ * - supports tcl driver
+ * - may be extended in future versions with new cmd types, packets
+ */
+typedef struct drm_radeon_cmd_buffer {
+ int bufsz;
+ char *buf;
+ int nbox;
+ drm_clip_rect_t *boxes;
+} drm_radeon_cmd_buffer_t;
typedef struct drm_radeon_tex_image {
unsigned int x, y; /* Blit coordinates */
@@ -367,4 +453,15 @@ typedef struct drm_radeon_indirect {
int discard;
} drm_radeon_indirect_t;
+
+/* 1.3: An ioctl to get parameters that aren't available to the 3d
+ * client any other way.
+ */
+#define RADEON_PARAM_AGP_BUFFER_OFFSET 0x1
+
+typedef struct drm_radeon_getparam {
+ int param;
+ int *value;
+} drm_radeon_getparam_t;
+
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c
index 135dd184f..e4af560b8 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c
@@ -39,10 +39,10 @@
#define DRIVER_NAME "radeon"
#define DRIVER_DESC "ATI Radeon"
-#define DRIVER_DATE "20020602"
+#define DRIVER_DATE "20020611"
#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 2
+#define DRIVER_MINOR 3
#define DRIVER_PATCHLEVEL 1
/* Interface history:
@@ -51,6 +51,10 @@
* 1.2 - Add vertex2 ioctl (keith)
* - Add stencil capability to clear ioctl (gareth, keith)
* - Increase MAX_TEXTURE_LEVELS (brian)
+ * 1.3 - Add cmdbuf ioctl (keith)
+ * - Add support for new radeon packets (keith)
+ * - Add getparam ioctl (keith)
+ * - Add flip-buffers ioctl, deprecate fullscreen foo (keith).
*/
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \
@@ -68,17 +72,10 @@
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 },
-
-
-#if 0
-/* GH: Count data sent to card via ring or vertex/indirect buffers.
- */
-#define __HAVE_COUNTERS 3
-#define __HAVE_COUNTER6 _DRM_STAT_IRQ
-#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY
-#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY
-#endif
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)] = { radeon_cp_flip, 1, 0 },
#include "drm_agpsupport.h"
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h
index d6a900789..ba9f8de98 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h
@@ -74,14 +74,7 @@ typedef struct drm_radeon_private {
drm_radeon_freelist_t *head;
drm_radeon_freelist_t *tail;
-/* FIXME: ROTATE_BUFS is a hask to cycle through bufs until freelist
- code is used. Note this hides a problem with the scratch register
- (used to keep track of last buffer completed) being written to before
- the last buffer has actually completed rendering. */
-#define ROTATE_BUFS 1
-#if ROTATE_BUFS
int last_buf;
-#endif
volatile u32 *scratch;
int usec_timeout;
@@ -123,10 +116,6 @@ typedef struct drm_radeon_private {
typedef struct drm_radeon_buf_priv {
u32 age;
- int prim;
- int discard;
- int dispatched;
- drm_radeon_freelist_t *list_entry;
} drm_radeon_buf_priv_t;
/* radeon_cp.c */
@@ -181,6 +170,13 @@ extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_vertex2( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
+extern int radeon_cp_cmdbuf( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int radeon_cp_getparam( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int radeon_cp_flip( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+
/* Register definitions, register access macros and drmAddMap constants
@@ -209,8 +205,6 @@ extern int radeon_cp_vertex2( struct inode *inode, struct file *filp,
# define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16)
#define RADEON_RB3D_COLORPITCH 0x1c48
-#define RADEON_RB3D_DEPTHCLEARVALUE 0x1c30
-#define RADEON_RB3D_DEPTHXY_OFFSET 0x1c60
#define RADEON_DP_GUI_MASTER_CNTL 0x146c
# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
@@ -301,9 +295,6 @@ extern int radeon_cp_vertex2( struct inode *inode, struct file *filp,
# define RADEON_ROP_ENABLE (1 << 6)
# define RADEON_STENCIL_ENABLE (1 << 7)
# define RADEON_Z_ENABLE (1 << 8)
-# define RADEON_DEPTH_XZ_OFFEST_ENABLE (1 << 9)
-# define RADEON_ZBLOCK8 (0 << 15)
-# define RADEON_ZBLOCK16 (1 << 15)
#define RADEON_RB3D_DEPTHOFFSET 0x1c24
#define RADEON_RB3D_PLANEMASK 0x1d84
#define RADEON_RB3D_STENCILREFMASK 0x1d7c
@@ -369,6 +360,15 @@ extern int radeon_cp_vertex2( struct inode *inode, struct file *filp,
#define RADEON_SE_LINE_WIDTH 0x1db8
#define RADEON_SE_VPORT_XSCALE 0x1d98
#define RADEON_SE_ZBIAS_FACTOR 0x1db0
+#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED 0x2210
+#define RADEON_SE_TCL_OUTPUT_VTX_FMT 0x2254
+#define RADEON_SE_TCL_VECTOR_INDX_REG 0x2200
+# define RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT 16
+# define RADEON_VEC_INDX_DWORD_COUNT_SHIFT 28
+#define RADEON_SE_TCL_VECTOR_DATA_REG 0x2204
+#define RADEON_SE_TCL_SCALAR_INDX_REG 0x2208
+# define RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT 16
+#define RADEON_SE_TCL_SCALAR_DATA_REG 0x220C
#define RADEON_SURFACE_ACCESS_FLAGS 0x0bf8
#define RADEON_SURFACE_ACCESS_CLR 0x0bfc
#define RADEON_SURFACE_CNTL 0x0b00
@@ -470,8 +470,10 @@ extern int radeon_cp_vertex2( struct inode *inode, struct file *filp,
#define RADEON_CP_PACKET3 0xC0000000
# define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300
# define RADEON_WAIT_FOR_IDLE 0x00002600
+# define RADEON_3D_DRAW_VBUF 0x00002800
# define RADEON_3D_DRAW_IMMD 0x00002900
-# define RADEON_3D_CLEAR_ZMASK 0x00003200
+# define RADEON_3D_DRAW_INDX 0x00002A00
+# define RADEON_3D_LOAD_VBPNTR 0x00002F00
# define RADEON_CNTL_HOSTDATA_BLT 0x00009400
# define RADEON_CNTL_PAINT_MULTI 0x00009A00
# define RADEON_CNTL_BITBLT_MULTI 0x00009B00
@@ -483,6 +485,7 @@ extern int radeon_cp_vertex2( struct inode *inode, struct file *filp,
#define RADEON_CP_PACKET1_REG1_MASK 0x003ff800
#define RADEON_VTX_Z_PRESENT (1 << 31)
+#define RADEON_VTX_PKCOLOR_PRESENT (1 << 3)
#define RADEON_PRIM_TYPE_NONE (0 << 0)
#define RADEON_PRIM_TYPE_POINT (1 << 0)
@@ -696,7 +699,7 @@ do { \
#define RADEON_VERBOSE 0
-#define RING_LOCALS int write; unsigned int mask; volatile u32 *ring;
+#define RING_LOCALS int write, _nr; unsigned int mask; volatile u32 *ring;
#define BEGIN_RING( n ) do { \
if ( RADEON_VERBOSE ) { \
@@ -704,9 +707,10 @@ do { \
n, __FUNCTION__ ); \
} \
if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \
+ COMMIT_RING(); \
radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \
} \
- dev_priv->ring.space -= (n) * sizeof(u32); \
+ _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \
ring = dev_priv->ring.start; \
write = dev_priv->ring.tail; \
mask = dev_priv->ring.tail_mask; \
@@ -717,9 +721,17 @@ do { \
DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \
write, dev_priv->ring.tail ); \
} \
- radeon_flush_write_combine(); \
- dev_priv->ring.tail = write; \
- RADEON_WRITE( RADEON_CP_RB_WPTR, write ); \
+ if (((dev_priv->ring.tail + _nr) & mask) != write) { \
+ DRM_ERROR( \
+ "ADVANCE_RING(): mismatch: nr: %x write: %x\n", \
+ ((dev_priv->ring.tail + _nr) & mask), \
+ write); \
+ } else \
+ dev_priv->ring.tail = write; \
+} while (0)
+
+#define COMMIT_RING() do { \
+ RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \
} while (0)
#define OUT_RING( x ) do { \
@@ -736,6 +748,30 @@ do { \
OUT_RING( val ); \
} while (0)
+
+#define OUT_RING_USER_TABLE( tab, sz ) do { \
+ int _size = (sz); \
+ int *_tab = (tab); \
+ \
+ if (write + _size > mask) { \
+ int i = (mask+1) - write; \
+ if (__copy_from_user( (int *)(ring+write), \
+ _tab, i*4 )) \
+ return -EFAULT; \
+ write = 0; \
+ _size -= i; \
+ _tab += i; \
+ } \
+ \
+ if (_size && __copy_from_user( (int *)(ring+write), \
+ _tab, _size*4 )) \
+ return -EFAULT; \
+ \
+ write += _size; \
+ write &= mask; \
+} while (0)
+
+
#define RADEON_PERFORMANCE_BOXES 0
#endif /* __RADEON_DRV_H__ */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c
index cc518a0e1..08a8f8a83 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c
@@ -49,329 +49,210 @@ static inline void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv,
box->x1, box->y1, box->x2, box->y2 );
BEGIN_RING( 4 );
-
OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) );
OUT_RING( (box->y1 << 16) | box->x1 );
-
OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) );
- OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) );
-
- ADVANCE_RING();
-}
-
-static inline void radeon_emit_context( drm_radeon_private_t *dev_priv,
- drm_radeon_context_regs_t *ctx )
-{
- RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
-
- BEGIN_RING( 14 );
-
- OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) );
- OUT_RING( ctx->pp_misc );
- OUT_RING( ctx->pp_fog_color );
- OUT_RING( ctx->re_solid_color );
- OUT_RING( ctx->rb3d_blendcntl );
- OUT_RING( ctx->rb3d_depthoffset );
- OUT_RING( ctx->rb3d_depthpitch );
- OUT_RING( ctx->rb3d_zstencilcntl );
-
- OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 2 ) );
- OUT_RING( ctx->pp_cntl );
- OUT_RING( ctx->rb3d_cntl );
- OUT_RING( ctx->rb3d_coloroffset );
-
- OUT_RING( CP_PACKET0( RADEON_RB3D_COLORPITCH, 0 ) );
- OUT_RING( ctx->rb3d_colorpitch );
-
- ADVANCE_RING();
-}
-
-static inline void radeon_emit_vertfmt( drm_radeon_private_t *dev_priv,
- drm_radeon_context_regs_t *ctx )
-{
- RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
-
- BEGIN_RING( 2 );
-
- OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) );
- OUT_RING( ctx->se_coord_fmt );
-
- ADVANCE_RING();
-}
-
-static inline void radeon_emit_line( drm_radeon_private_t *dev_priv,
- drm_radeon_context_regs_t *ctx )
-{
- RING_LOCALS;
-/* printk( " %s %x %x %x\n", __FUNCTION__, */
-/* ctx->re_line_pattern, */
-/* ctx->re_line_state, */
-/* ctx->se_line_width); */
-
- BEGIN_RING( 5 );
-
- OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) );
- OUT_RING( ctx->re_line_pattern );
- OUT_RING( ctx->re_line_state );
-
- OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) );
- OUT_RING( ctx->se_line_width );
-
- ADVANCE_RING();
-}
-
-static inline void radeon_emit_bumpmap( drm_radeon_private_t *dev_priv,
- drm_radeon_context_regs_t *ctx )
-{
- RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
-
- BEGIN_RING( 5 );
-
- OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) );
- OUT_RING( ctx->pp_lum_matrix );
-
- OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) );
- OUT_RING( ctx->pp_rot_matrix_0 );
- OUT_RING( ctx->pp_rot_matrix_1 );
-
- ADVANCE_RING();
-}
-
-static inline void radeon_emit_masks( drm_radeon_private_t *dev_priv,
- drm_radeon_context_regs_t *ctx )
-{
- RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
-
- BEGIN_RING( 4 );
-
- OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) );
- OUT_RING( ctx->rb3d_stencilrefmask );
- OUT_RING( ctx->rb3d_ropcntl );
- OUT_RING( ctx->rb3d_planemask );
-
- ADVANCE_RING();
-}
-
-static inline void radeon_emit_viewport( drm_radeon_private_t *dev_priv,
- drm_radeon_context_regs_t *ctx )
-{
- RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
-
- BEGIN_RING( 7 );
-
- OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) );
- OUT_RING( ctx->se_vport_xscale );
- OUT_RING( ctx->se_vport_xoffset );
- OUT_RING( ctx->se_vport_yscale );
- OUT_RING( ctx->se_vport_yoffset );
- OUT_RING( ctx->se_vport_zscale );
- OUT_RING( ctx->se_vport_zoffset );
- ADVANCE_RING();
-}
-
-static inline void radeon_emit_setup( drm_radeon_private_t *dev_priv,
- drm_radeon_context_regs_t *ctx )
-{
- RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
-
- BEGIN_RING( 4 );
-
- OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) );
- OUT_RING( ctx->se_cntl );
- OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) );
- OUT_RING( ctx->se_cntl_status );
-
- ADVANCE_RING();
-}
-
-
-static inline void radeon_emit_misc( drm_radeon_private_t *dev_priv,
- drm_radeon_context_regs_t *ctx )
-{
- RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
-
- BEGIN_RING( 2 );
-
- OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) );
- OUT_RING( ctx->re_misc );
-
- ADVANCE_RING();
-}
-
-static inline void radeon_emit_tex0( drm_radeon_private_t *dev_priv,
- drm_radeon_texture_regs_t *tex )
-{
- RING_LOCALS;
- DRM_DEBUG( " %s: offset=0x%x\n", __FUNCTION__, tex->pp_txoffset );
-
- BEGIN_RING( 9 );
-
- OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) );
- OUT_RING( tex->pp_txfilter );
- OUT_RING( tex->pp_txformat );
- OUT_RING( tex->pp_txoffset );
- OUT_RING( tex->pp_txcblend );
- OUT_RING( tex->pp_txablend );
- OUT_RING( tex->pp_tfactor );
-
- OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) );
- OUT_RING( tex->pp_border_color );
-
- ADVANCE_RING();
-}
-
-static inline void radeon_emit_tex1( drm_radeon_private_t *dev_priv,
- drm_radeon_texture_regs_t *tex )
-{
- RING_LOCALS;
- DRM_DEBUG( " %s: offset=0x%x\n", __FUNCTION__, tex->pp_txoffset );
-
- BEGIN_RING( 9 );
-
- OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) );
- OUT_RING( tex->pp_txfilter );
- OUT_RING( tex->pp_txformat );
- OUT_RING( tex->pp_txoffset );
- OUT_RING( tex->pp_txcblend );
- OUT_RING( tex->pp_txablend );
- OUT_RING( tex->pp_tfactor );
-
- OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) );
- OUT_RING( tex->pp_border_color );
-
+/* OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) );*/
+ OUT_RING( (box->y2 << 16) | box->x2 );
ADVANCE_RING();
}
-static inline void radeon_emit_tex2( drm_radeon_private_t *dev_priv,
- drm_radeon_texture_regs_t *tex )
+/* Emit 1.1 state
+ */
+static void radeon_emit_state( drm_radeon_private_t *dev_priv,
+ drm_radeon_context_regs_t *ctx,
+ drm_radeon_texture_regs_t *tex,
+ unsigned int dirty )
{
RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
-
- BEGIN_RING( 9 );
-
- OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) );
- OUT_RING( tex->pp_txfilter );
- OUT_RING( tex->pp_txformat );
- OUT_RING( tex->pp_txoffset );
- OUT_RING( tex->pp_txcblend );
- OUT_RING( tex->pp_txablend );
- OUT_RING( tex->pp_tfactor );
-
- OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) );
- OUT_RING( tex->pp_border_color );
-
- ADVANCE_RING();
-}
-
-#if 0
-static void radeon_print_dirty( const char *msg, unsigned int flags )
-{
- DRM_DEBUG( "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s\n",
- msg,
- flags,
- (flags & RADEON_UPLOAD_CONTEXT) ? "context, " : "",
- (flags & RADEON_UPLOAD_VERTFMT) ? "vertfmt, " : "",
- (flags & RADEON_UPLOAD_LINE) ? "line, " : "",
- (flags & RADEON_UPLOAD_BUMPMAP) ? "bumpmap, " : "",
- (flags & RADEON_UPLOAD_MASKS) ? "masks, " : "",
- (flags & RADEON_UPLOAD_VIEWPORT) ? "viewport, " : "",
- (flags & RADEON_UPLOAD_SETUP) ? "setup, " : "",
- (flags & RADEON_UPLOAD_MISC) ? "misc, " : "",
- (flags & RADEON_UPLOAD_TEX0) ? "tex0, " : "",
- (flags & RADEON_UPLOAD_TEX1) ? "tex1, " : "",
- (flags & RADEON_UPLOAD_TEX2) ? "tex2, " : "",
- (flags & RADEON_UPLOAD_CLIPRECTS) ? "cliprects, " : "",
- (flags & RADEON_REQUIRE_QUIESCENCE) ? "quiescence, " : "" );
-}
-#endif
-
-static inline void radeon_emit_state( drm_radeon_private_t *dev_priv,
- drm_radeon_context_regs_t *ctx,
- drm_radeon_texture_regs_t *tex,
- unsigned int dirty )
-{
DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty );
if ( dirty & RADEON_UPLOAD_CONTEXT ) {
- radeon_emit_context( dev_priv, ctx );
+ BEGIN_RING( 14 );
+ OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) );
+ OUT_RING( ctx->pp_misc );
+ OUT_RING( ctx->pp_fog_color );
+ OUT_RING( ctx->re_solid_color );
+ OUT_RING( ctx->rb3d_blendcntl );
+ OUT_RING( ctx->rb3d_depthoffset );
+ OUT_RING( ctx->rb3d_depthpitch );
+ OUT_RING( ctx->rb3d_zstencilcntl );
+ OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 2 ) );
+ OUT_RING( ctx->pp_cntl );
+ OUT_RING( ctx->rb3d_cntl );
+ OUT_RING( ctx->rb3d_coloroffset );
+ OUT_RING( CP_PACKET0( RADEON_RB3D_COLORPITCH, 0 ) );
+ OUT_RING( ctx->rb3d_colorpitch );
+ ADVANCE_RING();
}
if ( dirty & RADEON_UPLOAD_VERTFMT ) {
- radeon_emit_vertfmt( dev_priv, ctx );
+ BEGIN_RING( 2 );
+ OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) );
+ OUT_RING( ctx->se_coord_fmt );
+ ADVANCE_RING();
}
if ( dirty & RADEON_UPLOAD_LINE ) {
- radeon_emit_line( dev_priv, ctx );
+ BEGIN_RING( 5 );
+ OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) );
+ OUT_RING( ctx->re_line_pattern );
+ OUT_RING( ctx->re_line_state );
+ OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) );
+ OUT_RING( ctx->se_line_width );
+ ADVANCE_RING();
}
if ( dirty & RADEON_UPLOAD_BUMPMAP ) {
- radeon_emit_bumpmap( dev_priv, ctx );
+ BEGIN_RING( 5 );
+ OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) );
+ OUT_RING( ctx->pp_lum_matrix );
+ OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) );
+ OUT_RING( ctx->pp_rot_matrix_0 );
+ OUT_RING( ctx->pp_rot_matrix_1 );
+ ADVANCE_RING();
}
if ( dirty & RADEON_UPLOAD_MASKS ) {
- radeon_emit_masks( dev_priv, ctx );
+ BEGIN_RING( 4 );
+ OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) );
+ OUT_RING( ctx->rb3d_stencilrefmask );
+ OUT_RING( ctx->rb3d_ropcntl );
+ OUT_RING( ctx->rb3d_planemask );
+ ADVANCE_RING();
}
if ( dirty & RADEON_UPLOAD_VIEWPORT ) {
- radeon_emit_viewport( dev_priv, ctx );
+ BEGIN_RING( 7 );
+ OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) );
+ OUT_RING( ctx->se_vport_xscale );
+ OUT_RING( ctx->se_vport_xoffset );
+ OUT_RING( ctx->se_vport_yscale );
+ OUT_RING( ctx->se_vport_yoffset );
+ OUT_RING( ctx->se_vport_zscale );
+ OUT_RING( ctx->se_vport_zoffset );
+ ADVANCE_RING();
}
if ( dirty & RADEON_UPLOAD_SETUP ) {
- radeon_emit_setup( dev_priv, ctx );
+ BEGIN_RING( 4 );
+ OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) );
+ OUT_RING( ctx->se_cntl );
+ OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) );
+ OUT_RING( ctx->se_cntl_status );
+ ADVANCE_RING();
}
if ( dirty & RADEON_UPLOAD_MISC ) {
- radeon_emit_misc( dev_priv, ctx );
+ BEGIN_RING( 2 );
+ OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) );
+ OUT_RING( ctx->re_misc );
+ ADVANCE_RING();
}
if ( dirty & RADEON_UPLOAD_TEX0 ) {
- radeon_emit_tex0( dev_priv, &tex[0] );
+ BEGIN_RING( 9 );
+ OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) );
+ OUT_RING( tex[0].pp_txfilter );
+ OUT_RING( tex[0].pp_txformat );
+ OUT_RING( tex[0].pp_txoffset );
+ OUT_RING( tex[0].pp_txcblend );
+ OUT_RING( tex[0].pp_txablend );
+ OUT_RING( tex[0].pp_tfactor );
+ OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) );
+ OUT_RING( tex[0].pp_border_color );
+ ADVANCE_RING();
}
if ( dirty & RADEON_UPLOAD_TEX1 ) {
- radeon_emit_tex1( dev_priv, &tex[1] );
+ BEGIN_RING( 9 );
+ OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) );
+ OUT_RING( tex[1].pp_txfilter );
+ OUT_RING( tex[1].pp_txformat );
+ OUT_RING( tex[1].pp_txoffset );
+ OUT_RING( tex[1].pp_txcblend );
+ OUT_RING( tex[1].pp_txablend );
+ OUT_RING( tex[1].pp_tfactor );
+ OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) );
+ OUT_RING( tex[1].pp_border_color );
+ ADVANCE_RING();
}
if ( dirty & RADEON_UPLOAD_TEX2 ) {
- radeon_emit_tex2( dev_priv, &tex[2] );
+ BEGIN_RING( 9 );
+ OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) );
+ OUT_RING( tex[2].pp_txfilter );
+ OUT_RING( tex[2].pp_txformat );
+ OUT_RING( tex[2].pp_txoffset );
+ OUT_RING( tex[2].pp_txcblend );
+ OUT_RING( tex[2].pp_txablend );
+ OUT_RING( tex[2].pp_tfactor );
+ OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) );
+ OUT_RING( tex[2].pp_border_color );
+ ADVANCE_RING();
}
}
-
-
-static inline void radeon_emit_zbias( drm_radeon_private_t *dev_priv,
- drm_radeon_context2_regs_t *ctx )
+/* Emit 1.2 state
+ */
+static void radeon_emit_state2( drm_radeon_private_t *dev_priv,
+ drm_radeon_state_t *state )
{
RING_LOCALS;
-/* printk( " %s %x %x\n", __FUNCTION__, */
-/* ctx->se_zbias_factor, */
-/* ctx->se_zbias_constant ); */
-
- BEGIN_RING( 3 );
- OUT_RING( CP_PACKET0( RADEON_SE_ZBIAS_FACTOR, 1 ) );
- OUT_RING( ctx->se_zbias_factor );
- OUT_RING( ctx->se_zbias_constant );
- ADVANCE_RING();
-}
-static inline void radeon_emit_state2( drm_radeon_private_t *dev_priv,
- drm_radeon_state_t *state )
-{
- if (state->dirty & RADEON_UPLOAD_ZBIAS)
- radeon_emit_zbias( dev_priv, &state->context2 );
+ if (state->dirty & RADEON_UPLOAD_ZBIAS) {
+ BEGIN_RING( 3 );
+ OUT_RING( CP_PACKET0( RADEON_SE_ZBIAS_FACTOR, 1 ) );
+ OUT_RING( state->context2.se_zbias_factor );
+ OUT_RING( state->context2.se_zbias_constant );
+ ADVANCE_RING();
+ }
radeon_emit_state( dev_priv, &state->context,
state->tex, state->dirty );
}
+/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in
+ * 1.3 cmdbuffers allow all previous state to be updated as well as
+ * the tcl scalar and vector areas.
+ */
+static struct {
+ int start;
+ int len;
+ const char *name;
+} packet[RADEON_MAX_STATE_PACKETS] = {
+ { RADEON_PP_MISC,7,"RADEON_PP_MISC" },
+ { RADEON_PP_CNTL,3,"RADEON_PP_CNTL" },
+ { RADEON_RB3D_COLORPITCH,1,"RADEON_RB3D_COLORPITCH" },
+ { RADEON_RE_LINE_PATTERN,2,"RADEON_RE_LINE_PATTERN" },
+ { RADEON_SE_LINE_WIDTH,1,"RADEON_SE_LINE_WIDTH" },
+ { RADEON_PP_LUM_MATRIX,1,"RADEON_PP_LUM_MATRIX" },
+ { RADEON_PP_ROT_MATRIX_0,2,"RADEON_PP_ROT_MATRIX_0" },
+ { RADEON_RB3D_STENCILREFMASK,3,"RADEON_RB3D_STENCILREFMASK" },
+ { RADEON_SE_VPORT_XSCALE,6,"RADEON_SE_VPORT_XSCALE" },
+ { RADEON_SE_CNTL,2,"RADEON_SE_CNTL" },
+ { RADEON_SE_CNTL_STATUS,1,"RADEON_SE_CNTL_STATUS" },
+ { RADEON_RE_MISC,1,"RADEON_RE_MISC" },
+ { RADEON_PP_TXFILTER_0,6,"RADEON_PP_TXFILTER_0" },
+ { RADEON_PP_BORDER_COLOR_0,1,"RADEON_PP_BORDER_COLOR_0" },
+ { RADEON_PP_TXFILTER_1,6,"RADEON_PP_TXFILTER_1" },
+ { RADEON_PP_BORDER_COLOR_1,1,"RADEON_PP_BORDER_COLOR_1" },
+ { RADEON_PP_TXFILTER_2,6,"RADEON_PP_TXFILTER_2" },
+ { RADEON_PP_BORDER_COLOR_2,1,"RADEON_PP_BORDER_COLOR_2" },
+ { RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" },
+ { RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" },
+ { RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" },
+};
+
+
+
+
+
+
+
+
+
+
#if RADEON_PERFORMANCE_BOXES
/* ================================================================
* Performance monitoring functions
@@ -552,7 +433,7 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
radeon_emit_clip_rect( dev_priv,
&sarea_priv->boxes[i] );
- BEGIN_RING( 25 );
+ BEGIN_RING( 28 );
RADEON_WAIT_UNTIL_2D_IDLE();
@@ -569,32 +450,32 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
OUT_RING_REG( RADEON_SE_CNTL,
depth_clear->se_cntl );
- OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 10 ) );
- OUT_RING( RADEON_VTX_Z_PRESENT );
+ /* Radeon 7500 doesn't like vertices without
+ * color.
+ */
+ OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 13 ) );
+ OUT_RING( RADEON_VTX_Z_PRESENT |
+ RADEON_VTX_PKCOLOR_PRESENT);
OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST |
RADEON_PRIM_WALK_RING |
RADEON_MAOS_ENABLE |
RADEON_VTX_FMT_RADEON_MODE |
(3 << RADEON_NUM_VERTICES_SHIFT)) );
-/* printk( "depth box %d: %x %x %x %x\n", */
-/* i, */
-/* depth_boxes[i].ui[CLEAR_X1], */
-/* depth_boxes[i].ui[CLEAR_Y1], */
-/* depth_boxes[i].ui[CLEAR_X2], */
-/* depth_boxes[i].ui[CLEAR_Y2]); */
-
OUT_RING( depth_boxes[i].ui[CLEAR_X1] );
OUT_RING( depth_boxes[i].ui[CLEAR_Y1] );
OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
+ OUT_RING( 0x0 );
OUT_RING( depth_boxes[i].ui[CLEAR_X1] );
OUT_RING( depth_boxes[i].ui[CLEAR_Y2] );
OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
+ OUT_RING( 0x0 );
OUT_RING( depth_boxes[i].ui[CLEAR_X2] );
OUT_RING( depth_boxes[i].ui[CLEAR_Y2] );
OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
+ OUT_RING( 0x0 );
ADVANCE_RING();
@@ -664,9 +545,17 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev )
RADEON_DP_SRC_SOURCE_MEMORY |
RADEON_GMC_CLR_CMP_CNTL_DIS |
RADEON_GMC_WR_MSK_DIS );
-
- OUT_RING( dev_priv->back_pitch_offset );
- OUT_RING( dev_priv->front_pitch_offset );
+
+ /* Make this work even if front & back are flipped:
+ */
+ if (dev_priv->current_page == 0) {
+ OUT_RING( dev_priv->back_pitch_offset );
+ OUT_RING( dev_priv->front_pitch_offset );
+ }
+ else {
+ OUT_RING( dev_priv->front_pitch_offset );
+ OUT_RING( dev_priv->back_pitch_offset );
+ }
OUT_RING( (x << 16) | y );
OUT_RING( (x << 16) | y );
@@ -701,11 +590,12 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev )
radeon_cp_performance_boxes( dev_priv );
#endif
- BEGIN_RING( 6 );
+ BEGIN_RING( 4 );
RADEON_WAIT_UNTIL_3D_IDLE();
+/*
RADEON_WAIT_UNTIL_PAGE_FLIPPED();
-
+*/
OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET, 0 ) );
if ( dev_priv->current_page == 0 ) {
@@ -723,6 +613,7 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev )
* performing the swapbuffer ioctl.
*/
dev_priv->sarea_priv->last_frame++;
+ dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page;
BEGIN_RING( 2 );
@@ -731,78 +622,75 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev )
ADVANCE_RING();
}
-
-static void radeon_cp_dispatch_vertex( drm_device_t *dev,
- drm_buf_t *buf,
- drm_radeon_prim_t *prim )
+static int bad_prim_vertex_nr( int primitive, int nr )
{
- drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
- int offset = dev_priv->agp_buffers_offset + buf->offset + prim->start;
- int numverts = (int)prim->numverts;
- int i = 0;
- RING_LOCALS;
-
- DRM_DEBUG( __FUNCTION__": nbox=%d %d..%d prim %x nvert %d\n",
- sarea_priv->nbox, prim->start, prim->finish,
- prim->prim, numverts );
-
- switch (prim->prim & RADEON_PRIM_TYPE_MASK) {
+ switch (primitive & RADEON_PRIM_TYPE_MASK) {
case RADEON_PRIM_TYPE_NONE:
case RADEON_PRIM_TYPE_POINT:
- if (prim->numverts < 1) {
- DRM_ERROR( "Bad nr verts for line %d\n",
- prim->numverts);
- return;
- }
- break;
+ return nr < 1;
case RADEON_PRIM_TYPE_LINE:
- if ((prim->numverts & 1) || prim->numverts == 0) {
- DRM_ERROR( "Bad nr verts for line %d\n",
- prim->numverts);
- return;
- }
- break;
+ return (nr & 1) || nr == 0;
case RADEON_PRIM_TYPE_LINE_STRIP:
- if (prim->numverts < 2) {
- DRM_ERROR( "Bad nr verts for line_strip %d\n",
- prim->numverts);
- return;
- }
- break;
+ return nr < 2;
case RADEON_PRIM_TYPE_TRI_LIST:
case RADEON_PRIM_TYPE_3VRT_POINT_LIST:
case RADEON_PRIM_TYPE_3VRT_LINE_LIST:
case RADEON_PRIM_TYPE_RECT_LIST:
- if (prim->numverts % 3 || prim->numverts == 0) {
- DRM_ERROR( "Bad nr verts for tri %d\n",
- prim->numverts);
- return;
- }
- break;
+ return nr % 3 || nr == 0;
case RADEON_PRIM_TYPE_TRI_FAN:
case RADEON_PRIM_TYPE_TRI_STRIP:
- if (prim->numverts < 3) {
- DRM_ERROR( "Bad nr verts for strip/fan %d\n",
- prim->numverts);
- return;
- }
- break;
+ return nr < 3;
default:
- DRM_ERROR( "buffer prim %x start %x\n",
- prim->prim, prim->start );
- return;
+ return 1;
}
+}
+
- buf_priv->dispatched = 1;
+typedef struct {
+ unsigned int start;
+ unsigned int finish;
+ unsigned int prim;
+ unsigned int numverts;
+ unsigned int offset;
+ unsigned int vc_format;
+} drm_radeon_tcl_prim_t;
+
+static void radeon_cp_dispatch_vertex( drm_device_t *dev,
+ drm_buf_t *buf,
+ drm_radeon_tcl_prim_t *prim,
+ drm_clip_rect_t *boxes,
+ int nbox )
+
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ drm_clip_rect_t box;
+ int offset = dev_priv->agp_buffers_offset + buf->offset + prim->start;
+ int numverts = (int)prim->numverts;
+ int i = 0;
+ RING_LOCALS;
+
+ DRM_DEBUG("%s: hwprim 0x%x vfmt 0x%x %d..%d %d verts\n",
+ __FUNCTION__,
+ prim->prim,
+ prim->vc_format,
+ prim->start,
+ prim->finish,
+ prim->numverts);
+
+ if (bad_prim_vertex_nr( prim->prim, prim->numverts )) {
+ DRM_ERROR( "bad prim %x numverts %d\n",
+ prim->prim, prim->numverts );
+ return;
+ }
do {
/* Emit the next cliprect */
- if ( i < sarea_priv->nbox ) {
- radeon_emit_clip_rect( dev_priv,
- &sarea_priv->boxes[i] );
+ if ( i < nbox ) {
+ if (__copy_from_user( &box, &boxes[i], sizeof(box) ))
+ return;
+
+ radeon_emit_clip_rect( dev_priv, &box );
}
/* Emit the vertex buffer rendering commands */
@@ -820,19 +708,18 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev,
ADVANCE_RING();
i++;
- } while ( i < sarea_priv->nbox );
-
- dev_priv->sarea_priv->last_dispatch++;
+ } while ( i < nbox );
}
+
static void radeon_cp_discard_buffer( drm_device_t *dev, drm_buf_t *buf )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
RING_LOCALS;
- buf_priv->age = dev_priv->sarea_priv->last_dispatch;
+ buf_priv->age = ++dev_priv->sarea_priv->last_dispatch;
/* Emit the vertex buffer age */
BEGIN_RING( 2 );
@@ -841,8 +728,6 @@ static void radeon_cp_discard_buffer( drm_device_t *dev, drm_buf_t *buf )
buf->pending = 1;
buf->used = 0;
- /* FIXME: Check dispatched field */
- buf_priv->dispatched = 0;
}
static void radeon_cp_dispatch_indirect( drm_device_t *dev,
@@ -850,7 +735,6 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev,
int start, int end )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
RING_LOCALS;
DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",
buf->idx, start, end );
@@ -871,8 +755,6 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev,
data[dwords++] = RADEON_CP_PACKET2;
}
- buf_priv->dispatched = 1;
-
/* Fire off the indirect buffer */
BEGIN_RING( 3 );
@@ -882,112 +764,76 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev,
ADVANCE_RING();
}
-
- dev_priv->sarea_priv->last_dispatch++;
}
+
static void radeon_cp_dispatch_indices( drm_device_t *dev,
drm_buf_t *elt_buf,
- drm_radeon_prim_t *prim )
+ drm_radeon_tcl_prim_t *prim,
+ drm_clip_rect_t *boxes,
+ int nbox )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_radeon_buf_priv_t *buf_priv = elt_buf->dev_private;
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- int offset = dev_priv->agp_buffers_offset + prim->numverts * 64;
+ drm_clip_rect_t box;
+ int offset = dev_priv->agp_buffers_offset + prim->offset;
u32 *data;
int dwords;
int i = 0;
int start = prim->start + RADEON_INDEX_PRIM_OFFSET;
int count = (prim->finish - start) / sizeof(u16);
- DRM_DEBUG( "indices: start=%x/%x end=%x count=%d nv %d offset %x\n",
- prim->start, start, prim->finish,
- count, prim->numverts, offset );
-
- switch (prim->prim & RADEON_PRIM_TYPE_MASK) {
- case RADEON_PRIM_TYPE_NONE:
- case RADEON_PRIM_TYPE_POINT:
- if (count < 1) {
- DRM_ERROR( "Bad nr verts %d\n",
- count);
- return;
- }
- break;
- case RADEON_PRIM_TYPE_LINE:
- if ((count & 1) || count == 0) {
- DRM_ERROR( "Bad nr verts for line %d\n",
- count);
- return;
- }
- break;
- case RADEON_PRIM_TYPE_LINE_STRIP:
- if (count < 2) {
- DRM_ERROR( "Bad nr verts for line_strip %d\n",
- count);
- return;
- }
- break;
- case RADEON_PRIM_TYPE_TRI_LIST:
- case RADEON_PRIM_TYPE_3VRT_POINT_LIST:
- case RADEON_PRIM_TYPE_3VRT_LINE_LIST:
- case RADEON_PRIM_TYPE_RECT_LIST:
- if (count % 3 || count == 0) {
- DRM_ERROR( "Bad nr verts for tri %d\n", count);
- return;
- }
- break;
- case RADEON_PRIM_TYPE_TRI_FAN:
- case RADEON_PRIM_TYPE_TRI_STRIP:
- if (count < 3) {
- DRM_ERROR( "Bad nr verts for strip/fan %d\n", count);
- return;
- }
- break;
- default:
- DRM_ERROR( "buffer prim %x start %x\n",
- prim->prim, prim->start );
+ DRM_DEBUG("%s: hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n",
+ __FUNCTION__,
+ prim->prim,
+ prim->vc_format,
+ prim->start,
+ prim->finish,
+ prim->offset,
+ prim->numverts);
+
+ if (bad_prim_vertex_nr( prim->prim, count )) {
+ DRM_ERROR( "bad prim %x count %d\n",
+ prim->prim, count );
return;
- }
+ }
- if ( start < prim->finish ) {
- buf_priv->dispatched = 1;
- dwords = (prim->finish - prim->start + 3) / sizeof(u32);
+ if ( start >= prim->finish ||
+ (prim->start & 0x7) ) {
+ DRM_ERROR( "buffer prim %d\n", prim->prim );
+ return;
+ }
- data = (u32 *)((char *)dev_priv->buffers->handle +
- elt_buf->offset + prim->start);
+ dwords = (prim->finish - prim->start + 3) / sizeof(u32);
- data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 );
- data[1] = offset;
- data[2] = RADEON_MAX_VB_VERTS;
- data[3] = prim->vc_format;
- data[4] = (prim->prim |
- RADEON_PRIM_WALK_IND |
- RADEON_COLOR_ORDER_RGBA |
- RADEON_VTX_FMT_RADEON_MODE |
- (count << RADEON_NUM_VERTICES_SHIFT) );
+ data = (u32 *)((char *)dev_priv->buffers->handle +
+ elt_buf->offset + prim->start);
- if ( count & 0x1 ) {
- /* unnecessary? */
- data[dwords-1] &= 0x0000ffff;
- }
+ data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 );
+ data[1] = offset;
+ data[2] = prim->numverts;
+ data[3] = prim->vc_format;
+ data[4] = (prim->prim |
+ RADEON_PRIM_WALK_IND |
+ RADEON_COLOR_ORDER_RGBA |
+ RADEON_VTX_FMT_RADEON_MODE |
+ (count << RADEON_NUM_VERTICES_SHIFT) );
- do {
- /* Emit the next set of up to three cliprects */
- if ( i < sarea_priv->nbox ) {
- radeon_emit_clip_rect( dev_priv,
- &sarea_priv->boxes[i] );
- }
+ do {
+ if ( i < nbox ) {
+ if (__copy_from_user( &box, &boxes[i], sizeof(box) ))
+ return;
+
+ radeon_emit_clip_rect( dev_priv, &box );
+ }
- radeon_cp_dispatch_indirect( dev, elt_buf,
- prim->start,
- prim->finish );
+ radeon_cp_dispatch_indirect( dev, elt_buf,
+ prim->start,
+ prim->finish );
- i++;
- } while ( i < sarea_priv->nbox );
- }
+ i++;
+ } while ( i < nbox );
- sarea_priv->last_dispatch++;
}
#define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32))
@@ -998,7 +844,6 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
{
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_buf_t *buf;
- drm_radeon_buf_priv_t *buf_priv;
u32 format;
u32 *buffer;
u8 *data;
@@ -1016,8 +861,6 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
tex->offset >> 10, tex->pitch, tex->format,
image->x, image->y, image->width, image->height );
- buf_priv = buf->dev_private;
-
/* The compiler won't optimize away a division by a variable,
* even if the only legal values are powers of two. Thus, we'll
* use a shift instead.
@@ -1153,7 +996,6 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
buf->pid = current->pid;
buf->used = (dwords + 8) * sizeof(u32);
- buf_priv->discard = 1;
radeon_cp_dispatch_indirect( dev, buf, 0, buf->used );
radeon_cp_discard_buffer( dev, buf );
@@ -1223,25 +1065,73 @@ int radeon_cp_clear( struct inode *inode, struct file *filp,
sarea_priv->nbox * sizeof(depth_boxes[0]) ) )
return -EFAULT;
- /* Needed for depth clears via triangles???
- */
- if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
- radeon_emit_state( dev_priv,
- &sarea_priv->context_state,
- sarea_priv->tex_state,
- sarea_priv->dirty );
+ radeon_cp_dispatch_clear( dev, &clear, depth_boxes );
- sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
- RADEON_UPLOAD_TEX1IMAGES |
- RADEON_UPLOAD_TEX2IMAGES |
- RADEON_REQUIRE_QUIESCENCE);
- }
+ COMMIT_RING();
+ return 0;
+}
- radeon_cp_dispatch_clear( dev, &clear, depth_boxes );
+
+
+/* Not sure why this isn't set all the time:
+ */
+static int radeon_do_init_pageflip( drm_device_t *dev )
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ dev_priv->crtc_offset = RADEON_READ( RADEON_CRTC_OFFSET );
+ dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL );
+
+ RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->front_offset );
+ RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL,
+ dev_priv->crtc_offset_cntl |
+ RADEON_CRTC_OFFSET_FLIP_CNTL );
+
+ dev_priv->page_flipping = 1;
+ dev_priv->current_page = 0;
+
+ return 0;
+}
+
+int radeon_do_cleanup_pageflip( drm_device_t *dev )
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->crtc_offset );
+ RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
+
+ dev_priv->page_flipping = 0;
+ dev_priv->current_page = 0;
return 0;
}
+/* Swapping and flipping are different operations, need different ioctls.
+ * They can & should be intermixed to support multiple 3d windows.
+ */
+int radeon_cp_flip( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ LOCK_TEST_WITH_RETURN( dev );
+
+ RING_SPACE_TEST_WITH_RETURN( dev_priv );
+
+ if (!dev_priv->page_flipping)
+ radeon_do_init_pageflip( dev );
+
+ radeon_cp_dispatch_flip( dev );
+
+ COMMIT_RING();
+ return 0;
+}
+
int radeon_cp_swap( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
@@ -1258,13 +1148,10 @@ int radeon_cp_swap( struct inode *inode, struct file *filp,
if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS )
sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
- if ( !dev_priv->page_flipping ) {
- radeon_cp_dispatch_swap( dev );
- dev_priv->sarea_priv->ctx_owner = 0;
- } else {
- radeon_cp_dispatch_flip( dev );
- }
+ radeon_cp_dispatch_swap( dev );
+ dev_priv->sarea_priv->ctx_owner = 0;
+ COMMIT_RING();
return 0;
}
@@ -1277,9 +1164,8 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp,
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_device_dma_t *dma = dev->dma;
drm_buf_t *buf;
- drm_radeon_buf_priv_t *buf_priv;
drm_radeon_vertex_t vertex;
- drm_radeon_prim_t prim;
+ drm_radeon_tcl_prim_t prim;
LOCK_TEST_WITH_RETURN( dev );
@@ -1311,7 +1197,6 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp,
VB_AGE_TEST_WITH_RETURN( dev_priv );
buf = dma->buflist[vertex.idx];
- buf_priv = buf->dev_private;
if ( buf->pid != current->pid ) {
DRM_ERROR( "process %d using buffer owned by %d\n",
@@ -1323,9 +1208,11 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp,
return -EINVAL;
}
- buf->used = vertex.count; /* not used? */
-
+ /* Build up a prim_t record:
+ */
if (vertex.count) {
+ buf->used = vertex.count; /* not used? */
+
if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
radeon_emit_state( dev_priv,
&sarea_priv->context_state,
@@ -1338,22 +1225,22 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp,
RADEON_REQUIRE_QUIESCENCE);
}
- /* Build up a prim_t record:
- */
prim.start = 0;
prim.finish = vertex.count; /* unused */
prim.prim = vertex.prim;
- prim.stateidx = 0xff; /* unused */
prim.numverts = vertex.count;
prim.vc_format = dev_priv->sarea_priv->vc_format;
- radeon_cp_dispatch_vertex( dev, buf, &prim );
+ radeon_cp_dispatch_vertex( dev, buf, &prim,
+ dev_priv->sarea_priv->boxes,
+ dev_priv->sarea_priv->nbox );
}
if (vertex.discard) {
radeon_cp_discard_buffer( dev, buf );
}
+ COMMIT_RING();
return 0;
}
@@ -1366,9 +1253,8 @@ int radeon_cp_indices( struct inode *inode, struct file *filp,
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_device_dma_t *dma = dev->dma;
drm_buf_t *buf;
- drm_radeon_buf_priv_t *buf_priv;
drm_radeon_indices_t elts;
- drm_radeon_prim_t prim;
+ drm_radeon_tcl_prim_t prim;
int count;
LOCK_TEST_WITH_RETURN( dev );
@@ -1401,7 +1287,6 @@ int radeon_cp_indices( struct inode *inode, struct file *filp,
VB_AGE_TEST_WITH_RETURN( dev_priv );
buf = dma->buflist[elts.idx];
- buf_priv = buf->dev_private;
if ( buf->pid != current->pid ) {
DRM_ERROR( "process %d using buffer owned by %d\n",
@@ -1445,15 +1330,18 @@ int radeon_cp_indices( struct inode *inode, struct file *filp,
prim.start = elts.start;
prim.finish = elts.end;
prim.prim = elts.prim;
- prim.stateidx = 0xff; /* unused */
- prim.numverts = 0; /* indexed from start of dma area */
+ prim.offset = 0; /* offset from start of dma buffers */
+ prim.numverts = RADEON_MAX_VB_VERTS; /* duh */
prim.vc_format = dev_priv->sarea_priv->vc_format;
- radeon_cp_dispatch_indices( dev, buf, &prim );
+ radeon_cp_dispatch_indices( dev, buf, &prim,
+ dev_priv->sarea_priv->boxes,
+ dev_priv->sarea_priv->nbox );
if (elts.discard) {
- radeon_cp_discard_buffer( dev, buf );
+ radeon_cp_discard_buffer( dev, buf );
}
+ COMMIT_RING();
return 0;
}
@@ -1465,6 +1353,7 @@ int radeon_cp_texture( struct inode *inode, struct file *filp,
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_texture_t tex;
drm_radeon_tex_image_t image;
+ int ret;
LOCK_TEST_WITH_RETURN( dev );
@@ -1484,7 +1373,10 @@ int radeon_cp_texture( struct inode *inode, struct file *filp,
RING_SPACE_TEST_WITH_RETURN( dev_priv );
VB_AGE_TEST_WITH_RETURN( dev_priv );
- return radeon_cp_dispatch_texture( dev, &tex, &image );
+ ret = radeon_cp_dispatch_texture( dev, &tex, &image );
+
+ COMMIT_RING();
+ return ret;
}
int radeon_cp_stipple( struct inode *inode, struct file *filp,
@@ -1509,6 +1401,7 @@ int radeon_cp_stipple( struct inode *inode, struct file *filp,
radeon_cp_dispatch_stipple( dev, mask );
+ COMMIT_RING();
return 0;
}
@@ -1520,7 +1413,6 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp,
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_device_dma_t *dma = dev->dma;
drm_buf_t *buf;
- drm_radeon_buf_priv_t *buf_priv;
drm_radeon_indirect_t indirect;
RING_LOCALS;
@@ -1546,7 +1438,6 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp,
}
buf = dma->buflist[indirect.idx];
- buf_priv = buf->dev_private;
if ( buf->pid != current->pid ) {
DRM_ERROR( "process %d using buffer owned by %d\n",
@@ -1568,7 +1459,6 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp,
VB_AGE_TEST_WITH_RETURN( dev_priv );
buf->used = indirect.end;
- buf_priv->discard = indirect.discard;
/* Wait for the 3D stream to idle before the indirect buffer
* containing 2D acceleration commands is processed.
@@ -1585,10 +1475,11 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp,
*/
radeon_cp_dispatch_indirect( dev, buf, indirect.start, indirect.end );
if (indirect.discard) {
- radeon_cp_discard_buffer( dev, buf );
+ radeon_cp_discard_buffer( dev, buf );
}
+ COMMIT_RING();
return 0;
}
@@ -1598,9 +1489,9 @@ int radeon_cp_vertex2( struct inode *inode, struct file *filp,
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_radeon_private_t *dev_priv = dev->dev_private;
+ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_device_dma_t *dma = dev->dma;
drm_buf_t *buf;
- drm_radeon_buf_priv_t *buf_priv;
drm_radeon_vertex2_t vertex;
int i;
unsigned char laststate;
@@ -1629,7 +1520,6 @@ int radeon_cp_vertex2( struct inode *inode, struct file *filp,
VB_AGE_TEST_WITH_RETURN( dev_priv );
buf = dma->buflist[vertex.idx];
- buf_priv = buf->dev_private;
if ( buf->pid != current->pid ) {
DRM_ERROR( "process %d using buffer owned by %d\n",
@@ -1641,23 +1531,17 @@ int radeon_cp_vertex2( struct inode *inode, struct file *filp,
DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
return -EINVAL;
}
+
+ if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
+ return -EINVAL;
for (laststate = 0xff, i = 0 ; i < vertex.nr_prims ; i++) {
drm_radeon_prim_t prim;
+ drm_radeon_tcl_prim_t tclprim;
if ( copy_from_user( &prim, &vertex.prim[i], sizeof(prim) ) )
return -EFAULT;
-/* printk( "prim %d vfmt %x hwprim %x start %d finish %d\n", */
-/* i, prim.vc_format, prim.prim, */
-/* prim.start, prim.finish ); */
-
- if ( (prim.prim & RADEON_PRIM_TYPE_MASK) >
- RADEON_PRIM_TYPE_3VRT_LINE_LIST ) {
- DRM_ERROR( "buffer prim %d\n", prim.prim );
- return -EINVAL;
- }
-
if ( prim.stateidx != laststate ) {
drm_radeon_state_t state;
@@ -1666,34 +1550,346 @@ int radeon_cp_vertex2( struct inode *inode, struct file *filp,
sizeof(state) ) )
return -EFAULT;
-/* printk("emit state %d (%p) dirty %x\n", */
-/* prim.stateidx, */
-/* &vertex.state[prim.stateidx], */
-/* state.dirty); */
-
radeon_emit_state2( dev_priv, &state );
laststate = prim.stateidx;
}
- if ( prim.finish <= prim.start )
- continue;
-
- if ( prim.start & 0x7 ) {
- DRM_ERROR( "misaligned buffer 0x%x\n", prim.start );
- return -EINVAL;
- }
+ tclprim.start = prim.start;
+ tclprim.finish = prim.finish;
+ tclprim.prim = prim.prim;
+ tclprim.vc_format = prim.vc_format;
if ( prim.prim & RADEON_PRIM_WALK_IND ) {
- radeon_cp_dispatch_indices( dev, buf, &prim );
+ tclprim.offset = prim.numverts * 64;
+ tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */
+
+ radeon_cp_dispatch_indices( dev, buf, &tclprim,
+ sarea_priv->boxes,
+ sarea_priv->nbox);
} else {
- radeon_cp_dispatch_vertex( dev, buf, &prim );
+ tclprim.numverts = prim.numverts;
+ tclprim.offset = 0; /* not used */
+
+ radeon_cp_dispatch_vertex( dev, buf, &tclprim,
+ sarea_priv->boxes,
+ sarea_priv->nbox);
}
+
+ if (sarea_priv->nbox == 1)
+ sarea_priv->nbox = 0;
}
if ( vertex.discard ) {
radeon_cp_discard_buffer( dev, buf );
}
+ COMMIT_RING();
+ return 0;
+}
+
+
+static int radeon_emit_packets(
+ drm_radeon_private_t *dev_priv,
+ drm_radeon_cmd_header_t header,
+ drm_radeon_cmd_buffer_t *cmdbuf )
+{
+ int id = (int)header.packet.packet_id;
+ int sz = packet[id].len;
+ int reg = packet[id].start;
+ int *data = (int *)cmdbuf->buf;
+ RING_LOCALS;
+
+ if (sz * sizeof(int) > cmdbuf->bufsz)
+ return -EINVAL;
+
+ BEGIN_RING(sz+1);
+ OUT_RING( CP_PACKET0( reg, (sz-1) ) );
+ OUT_RING_USER_TABLE( data, sz );
+ ADVANCE_RING();
+
+ cmdbuf->buf += sz * sizeof(int);
+ cmdbuf->bufsz -= sz * sizeof(int);
+ return 0;
+}
+
+static inline int radeon_emit_scalars(
+ drm_radeon_private_t *dev_priv,
+ drm_radeon_cmd_header_t header,
+ drm_radeon_cmd_buffer_t *cmdbuf )
+{
+ int sz = header.scalars.count;
+ int *data = (int *)cmdbuf->buf;
+ int start = header.scalars.offset;
+ int stride = header.scalars.stride;
+ RING_LOCALS;
+
+ BEGIN_RING( 3+sz );
+ OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) );
+ OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
+ OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) );
+ OUT_RING_USER_TABLE( data, sz );
+ ADVANCE_RING();
+ cmdbuf->buf += sz * sizeof(int);
+ cmdbuf->bufsz -= sz * sizeof(int);
return 0;
}
+
+static inline int radeon_emit_vectors(
+ drm_radeon_private_t *dev_priv,
+ drm_radeon_cmd_header_t header,
+ drm_radeon_cmd_buffer_t *cmdbuf )
+{
+ int sz = header.vectors.count;
+ int *data = (int *)cmdbuf->buf;
+ int start = header.vectors.offset;
+ int stride = header.vectors.stride;
+ RING_LOCALS;
+
+ BEGIN_RING( 3+sz );
+ OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) );
+ OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
+ OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) );
+ OUT_RING_USER_TABLE( data, sz );
+ ADVANCE_RING();
+
+ cmdbuf->buf += sz * sizeof(int);
+ cmdbuf->bufsz -= sz * sizeof(int);
+ return 0;
+}
+
+
+static int radeon_emit_packet3( drm_device_t *dev,
+ drm_radeon_cmd_buffer_t *cmdbuf )
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ int cmdsz, tmp;
+ int *cmd = (int *)cmdbuf->buf;
+ RING_LOCALS;
+
+
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
+ if (__get_user( tmp, &cmd[0]))
+ return -EFAULT;
+
+ cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16);
+
+ if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 ||
+ cmdsz * 4 > cmdbuf->bufsz)
+ return -EINVAL;
+
+ BEGIN_RING( cmdsz );
+ OUT_RING_USER_TABLE( cmd, cmdsz );
+ ADVANCE_RING();
+
+ cmdbuf->buf += cmdsz * 4;
+ cmdbuf->bufsz -= cmdsz * 4;
+ return 0;
+}
+
+
+static int radeon_emit_packet3_cliprect( drm_device_t *dev,
+ drm_radeon_cmd_buffer_t *cmdbuf )
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ drm_clip_rect_t box;
+ int cmdsz, tmp;
+ int *cmd = (int *)cmdbuf->buf;
+ drm_clip_rect_t *boxes = cmdbuf->boxes;
+ int i = 0;
+ RING_LOCALS;
+
+ DRM_DEBUG("%s\n", __FUNCTION__);
+
+ if (__get_user( tmp, &cmd[0]))
+ return -EFAULT;
+
+ cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16);
+
+ if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 ||
+ cmdsz * 4 > cmdbuf->bufsz)
+ return -EINVAL;
+
+ do {
+ if ( i < cmdbuf->nbox ) {
+ if (__copy_from_user( &box, &boxes[i], sizeof(box) ))
+ return -EFAULT;
+ radeon_emit_clip_rect( dev_priv, &box );
+ }
+
+ BEGIN_RING( cmdsz );
+ OUT_RING_USER_TABLE( cmd, cmdsz );
+ ADVANCE_RING();
+
+ } while ( ++i < cmdbuf->nbox );
+
+ if (cmdbuf->nbox == 1)
+ cmdbuf->nbox = 0;
+
+ cmdbuf->buf += cmdsz * 4;
+ cmdbuf->bufsz -= cmdsz * 4;
+ return 0;
+}
+
+
+
+int radeon_cp_cmdbuf( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_t *buf = 0;
+ int idx;
+ drm_radeon_cmd_buffer_t cmdbuf;
+ drm_radeon_cmd_header_t header;
+
+ LOCK_TEST_WITH_RETURN( dev );
+
+ if ( !dev_priv ) {
+ DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ return -EINVAL;
+ }
+
+ if ( copy_from_user( &cmdbuf, (drm_radeon_cmd_buffer_t *)arg,
+ sizeof(cmdbuf) ) ) {
+ DRM_ERROR("copy_from_user\n");
+ return -EFAULT;
+ }
+
+ DRM_DEBUG( __FUNCTION__": pid=%d\n", current->pid );
+ RING_SPACE_TEST_WITH_RETURN( dev_priv );
+ VB_AGE_TEST_WITH_RETURN( dev_priv );
+
+
+ if (verify_area( VERIFY_READ, cmdbuf.buf, cmdbuf.bufsz ))
+ return -EFAULT;
+
+ if (cmdbuf.nbox &&
+ verify_area( VERIFY_READ, cmdbuf.boxes,
+ cmdbuf.nbox * sizeof(drm_clip_rect_t)))
+ return -EFAULT;
+
+ while ( cmdbuf.bufsz >= sizeof(header) ) {
+
+ if (__get_user( header.i, (int *)cmdbuf.buf )) {
+ DRM_ERROR("__get_user %p\n", cmdbuf.buf);
+ return -EFAULT;
+ }
+
+ cmdbuf.buf += sizeof(header);
+ cmdbuf.bufsz -= sizeof(header);
+
+ switch (header.header.cmd_type) {
+ case RADEON_CMD_PACKET:
+ if (radeon_emit_packets( dev_priv, header, &cmdbuf )) {
+ DRM_ERROR("radeon_emit_packets failed\n");
+ return -EINVAL;
+ }
+ break;
+
+ case RADEON_CMD_SCALARS:
+ if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) {
+ DRM_ERROR("radeon_emit_scalars failed\n");
+ return -EINVAL;
+ }
+ break;
+
+ case RADEON_CMD_VECTORS:
+ if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) {
+ DRM_ERROR("radeon_emit_vectors failed\n");
+ return -EINVAL;
+ }
+ break;
+
+ case RADEON_CMD_DMA_DISCARD:
+ idx = header.dma.buf_idx;
+ if ( idx < 0 || idx >= dma->buf_count ) {
+ DRM_ERROR( "buffer index %d (of %d max)\n",
+ idx, dma->buf_count - 1 );
+ return -EINVAL;
+ }
+
+ buf = dma->buflist[idx];
+ if ( buf->pid != current->pid || buf->pending ) {
+ DRM_ERROR( "bad buffer\n" );
+ return -EINVAL;
+ }
+
+ radeon_cp_discard_buffer( dev, buf );
+ break;
+
+ case RADEON_CMD_PACKET3:
+ if (radeon_emit_packet3( dev, &cmdbuf )) {
+ DRM_ERROR("radeon_emit_packet3 failed\n");
+ return -EINVAL;
+ }
+ break;
+
+ case RADEON_CMD_PACKET3_CLIP:
+ if (radeon_emit_packet3_cliprect( dev, &cmdbuf )) {
+ DRM_ERROR("radeon_emit_packet3_clip failed\n");
+ return -EINVAL;
+ }
+ break;
+
+ default:
+ DRM_ERROR("bad cmd_type %d at %p\n",
+ header.header.cmd_type,
+ cmdbuf.buf - sizeof(header));
+ return -EINVAL;
+ }
+ }
+
+
+ COMMIT_RING();
+ return 0;
+}
+
+
+
+int radeon_cp_getparam( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ drm_radeon_getparam_t param;
+ int value;
+
+ if ( !dev_priv ) {
+ DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ return -EINVAL;
+ }
+
+ if ( copy_from_user( &param, (drm_radeon_getparam_t *)arg,
+ sizeof(param) ) ) {
+ DRM_ERROR("copy_from_user\n");
+ return -EFAULT;
+ }
+
+ DRM_DEBUG( __FUNCTION__": pid=%d\n", current->pid );
+
+ switch( param.param ) {
+ case RADEON_PARAM_AGP_BUFFER_OFFSET:
+ value = dev_priv->agp_buffers_offset;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if ( copy_to_user( param.value, &value, sizeof(int) ) ) {
+ DRM_ERROR( "copy_to_user\n" );
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
index d116f3752..6ab295c48 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
@@ -84,6 +84,10 @@ typedef unsigned int drm_magic_t;
/* Warning: If you change this structure, make sure you change
* XF86DRIClipRectRec in the server as well */
+/* KW: Actually it's illegal to change either for
+ * backwards-compatibility reasons.
+ */
+
typedef struct drm_clip_rect {
unsigned short x1;
unsigned short y1;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
index d7859bbe7..a7b0b560d 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
@@ -218,6 +218,16 @@ typedef struct _drmTextureRegion {
unsigned int age;
} drmTextureRegion, *drmTextureRegionPtr;
+
+typedef struct _drmClipRect {
+ unsigned short x1; /* Upper left: inclusive */
+ unsigned short y1;
+ unsigned short x2; /* Lower right: exclusive */
+ unsigned short y2;
+} drmClipRect, *drmClipRectPtr;
+
+
+
#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)
#define DRM_LOCK_HELD 0x80000000 /* Hardware lock is held */