diff options
Diffstat (limited to 'xc/programs/Xserver')
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( ¶m, (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 */ |