⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r128_video.c

📁 x.org上有关ati系列显卡最新驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c,v 1.30 2003/11/10 18:22:18 tsi Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#include "r128.h"#include "r128_reg.h"#ifdef XF86DRI#include "r128_common.h"#include "r128_sarea.h"#endif#include "xf86.h"#include "dixstruct.h"#include <X11/extensions/Xv.h>#include "fourcc.h"#define OFF_DELAY       250  /* milliseconds */#define FREE_DELAY      15000#define OFF_TIMER       0x01#define FREE_TIMER      0x02#define CLIENT_VIDEO_ON 0x04#define TIMER_MASK      (OFF_TIMER | FREE_TIMER)static XF86VideoAdaptorPtr R128SetupImageVideo(ScreenPtr);static int  R128SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);static int  R128GetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer);static void R128StopVideo(ScrnInfoPtr, pointer, Bool);static void R128QueryBestSize(ScrnInfoPtr, Bool, short, short, short, short,			unsigned int *, unsigned int *, pointer);static int  R128PutImage(ScrnInfoPtr, short, short, short, short, short,			short, short, short, int, unsigned char*, short,			short, Bool, RegionPtr, pointer, DrawablePtr);static int  R128QueryImageAttributes(ScrnInfoPtr, int, unsigned short *,			unsigned short *,  int *, int *);static void R128ResetVideo(ScrnInfoPtr);static void R128VideoTimerCallback(ScrnInfoPtr pScrn, Time now);#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)static Atom xvBrightness, xvColorKey, xvSaturation, xvDoubleBuffer;typedef struct {   int           brightness;   int           saturation;   Bool          doubleBuffer;   unsigned char currentBuffer;   FBLinearPtr   linear;   RegionRec     clip;   CARD32        colorKey;   CARD32        videoStatus;   Time          offTime;   Time          freeTime;   int           ecp_div;} R128PortPrivRec, *R128PortPrivPtr;static void R128ECP(ScrnInfoPtr pScrn, R128PortPrivPtr pPriv){    R128InfoPtr     info      = R128PTR(pScrn);    unsigned char   *R128MMIO = info->MMIO;    int             dot_clock = info->ModeReg.dot_clock_freq;    if (dot_clock < 12500)      pPriv->ecp_div = 0;    else if (dot_clock < 25000) pPriv->ecp_div = 1;    else                        pPriv->ecp_div = 2;    OUTPLLP(pScrn, R128_VCLK_ECP_CNTL, pPriv->ecp_div<<8, ~R128_ECP_DIV_MASK);}void R128InitVideo(ScreenPtr pScreen){    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];    XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;    XF86VideoAdaptorPtr newAdaptor = NULL;    int num_adaptors;    newAdaptor = R128SetupImageVideo(pScreen);    num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);    if(newAdaptor) {	if(!num_adaptors) {	    num_adaptors = 1;	    adaptors = &newAdaptor;	} else {	    newAdaptors =  /* need to free this someplace */		xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*));	    if(newAdaptors) {		memcpy(newAdaptors, adaptors, num_adaptors *					sizeof(XF86VideoAdaptorPtr));		newAdaptors[num_adaptors] = newAdaptor;		adaptors = newAdaptors;		num_adaptors++;	    }	}    }    if(num_adaptors)	xf86XVScreenInit(pScreen, adaptors, num_adaptors);    if(newAdaptors)	xfree(newAdaptors);}#define MAXWIDTH 2048#define MAXHEIGHT 2048/* client libraries expect an encoding */static XF86VideoEncodingRec DummyEncoding ={   0,   "XV_IMAGE",   MAXWIDTH, MAXHEIGHT,   {1, 1}};#define NUM_FORMATS 12static XF86VideoFormatRec Formats[NUM_FORMATS] ={   {8, TrueColor}, {8, DirectColor}, {8, PseudoColor},   {8, GrayScale}, {8, StaticGray}, {8, StaticColor},   {15, TrueColor}, {16, TrueColor}, {24, TrueColor},   {15, DirectColor}, {16, DirectColor}, {24, DirectColor}};#define NUM_ATTRIBUTES 4static XF86AttributeRec Attributes[NUM_ATTRIBUTES] ={   {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},   {XvSettable | XvGettable, -64, 63, "XV_BRIGHTNESS"},   {XvSettable | XvGettable, 0, 31, "XV_SATURATION"},   {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}};#define NUM_IMAGES 4static XF86ImageRec Images[NUM_IMAGES] ={	XVIMAGE_YUY2,	XVIMAGE_UYVY,	XVIMAGE_YV12,	XVIMAGE_I420};static voidR128ResetVideo(ScrnInfoPtr pScrn){    R128InfoPtr   info      = R128PTR(pScrn);    unsigned char *R128MMIO = info->MMIO;    R128PortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;    OUTREG(R128_OV0_SCALE_CNTL, 0x80000000);    OUTREG(R128_OV0_EXCLUSIVE_HORZ, 0);    OUTREG(R128_OV0_AUTO_FLIP_CNTL, 0);   /* maybe */    OUTREG(R128_OV0_FILTER_CNTL, 0x0000000f);    OUTREG(R128_OV0_COLOUR_CNTL, (pPriv->brightness & 0x7f) |				 (pPriv->saturation << 8) |				 (pPriv->saturation << 16));    OUTREG(R128_OV0_GRAPHICS_KEY_MSK, (1 << pScrn->depth) - 1);    OUTREG(R128_OV0_GRAPHICS_KEY_CLR, pPriv->colorKey);    OUTREG(R128_OV0_KEY_CNTL, R128_GRAPHIC_KEY_FN_NE);    OUTREG(R128_OV0_TEST, 0);}static XF86VideoAdaptorPtrR128AllocAdaptor(ScrnInfoPtr pScrn){    XF86VideoAdaptorPtr adapt;    R128InfoPtr info = R128PTR(pScrn);    R128PortPrivPtr pPriv;    if(!(adapt = xf86XVAllocateVideoAdaptorRec(pScrn)))	return NULL;    if(!(pPriv = xcalloc(1, sizeof(R128PortPrivRec) + sizeof(DevUnion))))    {	xfree(adapt);	return NULL;    }    adapt->pPortPrivates = (DevUnion*)(&pPriv[1]);    adapt->pPortPrivates[0].ptr = (pointer)pPriv;    xvBrightness   = MAKE_ATOM("XV_BRIGHTNESS");    xvSaturation   = MAKE_ATOM("XV_SATURATION");    xvColorKey     = MAKE_ATOM("XV_COLORKEY");    xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");    pPriv->colorKey = info->videoKey;    pPriv->doubleBuffer = TRUE;    pPriv->videoStatus = 0;    pPriv->brightness = 0;    pPriv->saturation = 16;    pPriv->currentBuffer = 0;    R128ECP(pScrn, pPriv);    return adapt;}static XF86VideoAdaptorPtrR128SetupImageVideo(ScreenPtr pScreen){    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];    R128InfoPtr info = R128PTR(pScrn);    R128PortPrivPtr pPriv;    XF86VideoAdaptorPtr adapt;    if(!(adapt = R128AllocAdaptor(pScrn)))	return NULL;    adapt->type = XvWindowMask | XvInputMask | XvImageMask;    adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;    adapt->name = "ATI Rage128 Video Overlay";    adapt->nEncodings = 1;    adapt->pEncodings = &DummyEncoding;    adapt->nFormats = NUM_FORMATS;    adapt->pFormats = Formats;    adapt->nPorts = 1;    adapt->nAttributes = NUM_ATTRIBUTES;    adapt->pAttributes = Attributes;    adapt->nImages = NUM_IMAGES;    adapt->pImages = Images;    adapt->PutVideo = NULL;    adapt->PutStill = NULL;    adapt->GetVideo = NULL;    adapt->GetStill = NULL;    adapt->StopVideo = R128StopVideo;    adapt->SetPortAttribute = R128SetPortAttribute;    adapt->GetPortAttribute = R128GetPortAttribute;    adapt->QueryBestSize = R128QueryBestSize;    adapt->PutImage = R128PutImage;    adapt->QueryImageAttributes = R128QueryImageAttributes;    info->adaptor = adapt;    pPriv = (R128PortPrivPtr)(adapt->pPortPrivates[0].ptr);    REGION_NULL(pScreen, &(pPriv->clip));    R128ResetVideo(pScrn);    return adapt;}static voidR128StopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup){  R128InfoPtr info = R128PTR(pScrn);  unsigned char *R128MMIO = info->MMIO;  R128PortPrivPtr pPriv = (R128PortPrivPtr)data;  REGION_EMPTY(pScrn->pScreen, &pPriv->clip);  if(cleanup) {     if(pPriv->videoStatus & CLIENT_VIDEO_ON) {	OUTREG(R128_OV0_SCALE_CNTL, 0);     }     if(pPriv->linear) {	xf86FreeOffscreenLinear(pPriv->linear);	pPriv->linear = NULL;     }     pPriv->videoStatus = 0;  } else {     if(pPriv->videoStatus & CLIENT_VIDEO_ON) {	pPriv->videoStatus |= OFF_TIMER;	pPriv->offTime = currentTime.milliseconds + OFF_DELAY;     }  }}static intR128SetPortAttribute(  ScrnInfoPtr pScrn,  Atom attribute,  INT32 value,  pointer data){  R128InfoPtr info = R128PTR(pScrn);  unsigned char *R128MMIO = info->MMIO;  R128PortPrivPtr pPriv = (R128PortPrivPtr)data;  if(attribute == xvBrightness) {	if((value < -64) || (value > 63))	   return BadValue;	pPriv->brightness = value;	OUTREG(R128_OV0_COLOUR_CNTL, (pPriv->brightness & 0x7f) |				     (pPriv->saturation << 8) |				     (pPriv->saturation << 16));  } else  if(attribute == xvSaturation) {	if((value < 0) || (value > 31))	   return BadValue;	pPriv->saturation = value;	OUTREG(R128_OV0_COLOUR_CNTL, (pPriv->brightness & 0x7f) |				     (pPriv->saturation << 8) |				     (pPriv->saturation << 16));  } else  if(attribute == xvDoubleBuffer) {	if((value < 0) || (value > 1))	   return BadValue;	pPriv->doubleBuffer = value;  } else  if(attribute == xvColorKey) {	pPriv->colorKey = value;	OUTREG(R128_OV0_GRAPHICS_KEY_CLR, pPriv->colorKey);	REGION_EMPTY(pScrn->pScreen, &pPriv->clip);  } else return BadMatch;  return Success;}static intR128GetPortAttribute(  ScrnInfoPtr pScrn,  Atom attribute,  INT32 *value,  pointer data){  R128PortPrivPtr pPriv = (R128PortPrivPtr)data;  if(attribute == xvBrightness) {	*value = pPriv->brightness;  } else  if(attribute == xvSaturation) {	*value = pPriv->saturation;  } else  if(attribute == xvDoubleBuffer) {	*value = pPriv->doubleBuffer ? 1 : 0;  } else  if(attribute == xvColorKey) {	*value = pPriv->colorKey;  } else return BadMatch;  return Success;}static voidR128QueryBestSize(  ScrnInfoPtr pScrn,  Bool motion,  short vid_w, short vid_h,  short drw_w, short drw_h,  unsigned int *p_w, unsigned int *p_h,  pointer data){   if(vid_w > (drw_w << 4))	drw_w = vid_w >> 4;   if(vid_h > (drw_h << 4))	drw_h = vid_h >> 4;  *p_w = drw_w;  *p_h = drw_h;}/* * * R128DMA - abuse the texture blit ioctl to transfer rectangular blocks * * The block is split into 'passes' pieces of 'hpass' lines which fit entirely * into an indirect buffer * */static BoolR128DMA(  R128InfoPtr info,  unsigned char *src,  unsigned char *dst,  int srcPitch,  int dstPitch,  int h,  int w){#ifdef XF86DRI#define BUFSIZE (R128_BUFFER_SIZE - R128_HOSTDATA_BLIT_OFFSET)#define MAXPASSES (MAXHEIGHT/(BUFSIZE/(MAXWIDTH*2))+1)    unsigned char *buf;    int err=-1, i, idx, offset, hpass, passes, srcpassbytes, dstpassbytes;    int sizes[MAXPASSES], list[MAXPASSES];    drmDMAReq req;    drmR128Blit blit;    /* Verify conditions and bail out as early as possible */    if (!info->directRenderingEnabled || !info->DMAForXv)        return FALSE;    if ((hpass = min(h,(BUFSIZE/w))) == 0)	return FALSE;    if ((passes = (h+hpass-1)/hpass) > MAXPASSES)        return FALSE;    /* Request indirect buffers */    srcpassbytes = w*hpass;    req.context		= info->drmCtx;    req.send_count	= 0;    req.send_list	= NULL;    req.send_sizes	= NULL;    req.flags		= DRM_DMA_LARGER_OK;    req.request_count	= passes;    req.request_size	= srcpassbytes + R128_HOSTDATA_BLIT_OFFSET;    req.request_list	= &list[0];    req.request_sizes	= &sizes[0];    req.granted_count	= 0;    if (drmDMA(info->drmFD, &req))        return FALSE;    if (req.granted_count < passes) {        drmFreeBufs(info->drmFD, req.granted_count, req.request_list);	return FALSE;    }    /* Copy parts of the block into buffers and fire them */    dstpassbytes = hpass*dstPitch;    dstPitch /= 8;    for (i=0, offset=dst-info->FB; i<passes; i++, offset+=dstpassbytes) {        if (i == (passes-1) && (h % hpass) != 0) {	    hpass = h % hpass;	    srcpassbytes = w*hpass;	}	idx = req.request_list[i];	buf = (unsigned char *) info->buffers->list[idx].address + R128_HOSTDATA_BLIT_OFFSET;	if (srcPitch == w) {            memcpy(buf, src, srcpassbytes);	    src += srcpassbytes;	} else {	    int count = hpass;	    while(count--) {		memcpy(buf, src, w);		src += srcPitch;		buf += w;	    }	}        blit.idx = idx;        blit.offset = offset;        blit.pitch = dstPitch;        blit.format = (R128_DATATYPE_CI8 >> 16);        blit.x = (offset % 32);        blit.y = 0;        blit.width = w;        blit.height = hpass;	if ((err = drmCommandWrite(info->drmFD, DRM_R128_BLIT,                                   &blit, sizeof(drmR128Blit))) < 0)	    break;    }    drmFreeBufs(info->drmFD, req.granted_count, req.request_list);    return (err==0) ? TRUE : FALSE;#else    /* This is to avoid cluttering the rest of the code with '#ifdef XF86DRI' */    return FALSE;#endif	/* XF86DRI */}static voidR128CopyData422(  R128InfoPtr info,  unsigned char *src,  unsigned char *dst,  int srcPitch,  int dstPitch,  int h,  int w){    w <<= 1;    /* Attempt data transfer with DMA and fall back to memcpy */    if (!R128DMA(info, src, dst, srcPitch, dstPitch, h, w)) {        while(h--) {	    memcpy(dst, src, w);	    src += srcPitch;	    dst += dstPitch;	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -