radeon_vid.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 2,049 行 · 第 1/5 页

C
2,049
字号
    2048,    4,    4,    -1,    FLAG_UPSCALER | FLAG_DOWNSCALER | FLAG_EQUALIZER,    VENDOR_ATI,    0,    { 0, 0, 0, 0}};#if !defined(RAGE128) && defined(HAVE_X11)static void probe_fireGL_driver(void) {  Display *dp = XOpenDisplay ((void*)0);  int n = 0;  char **extlist;  if (dp==NULL) {       return;  }  extlist = XListExtensions (dp, &n);  XCloseDisplay (dp);  if (extlist) {    int i;    int ext_fgl = 0, ext_fglrx = 0;    for (i = 0; i < n; i++) {      if (!strcmp(extlist[i], "ATIFGLEXTENSION")) ext_fgl = 1;      if (!strcmp(extlist[i], "ATIFGLRXDRI")) ext_fglrx = 1;    }    if (ext_fgl) {      printf(RADEON_MSG" ATI FireGl driver detected");      firegl_shift = 0x500000;      if (!ext_fglrx) {        printf(", but DRI seems not to be activated\n");        printf(RADEON_MSG" Output may not work correctly, check your DRI configration!");      }      printf("\n");    }  }}#endifstatic int radeon_probe(int verbose, int force){  pciinfo_t lst[MAX_PCI_DEVICES];  unsigned i,num_pci;  int err;  __verbose = verbose;  err = pci_scan(lst,&num_pci);  if(err)  {    printf(RADEON_MSG" Error occurred during pci scan: %s\n",strerror(err));    return err;  }  else  {    err = ENXIO;    for(i=0;i<num_pci;i++)    {      if(lst[i].vendor == VENDOR_ATI)      {	int idx;	const char *dname;	idx = find_chip(lst[i].device);	if(idx == -1 && force == PROBE_NORMAL) continue;	dname = pci_device_name(VENDOR_ATI,lst[i].device);	dname = dname ? dname : "Unknown chip";	printf(RADEON_MSG" Found chip: %s\n",dname);#if 0        if ((lst[i].command & PCI_COMMAND_IO) == 0)        {          printf("[radeon] Device is disabled, ignoring\n");          continue;        }#endif	memset(&besr,0,sizeof(bes_registers_t));	if(force > PROBE_NORMAL)	{	    printf(RADEON_MSG" Driver was forced. Was found %sknown chip\n",idx == -1 ? "un" : "");	    if(idx == -1)#ifdef RAGE128		printf(RADEON_MSG" Assuming it as Rage128\n");#else		printf(RADEON_MSG" Assuming it as Radeon1\n");#endif	    besr.chip_flags=R_100|R_OVL_SHIFT;	}#if !defined(RAGE128) && defined(HAVE_X11)        probe_fireGL_driver();#endif	if(idx != -1) besr.chip_flags=ati_card_ids[idx].flags;	def_cap.device_id = lst[i].device;	err = 0;	memcpy(&pci_info,&lst[i],sizeof(pciinfo_t));	probed=1;	break;      }    }  }  if(err && verbose) printf(RADEON_MSG" Can't find chip\n");  return err;}typedef struct saved_regs_s{    uint32_t ov0_vid_key_clr;    uint32_t ov0_vid_key_msk;    uint32_t ov0_graphics_key_clr;    uint32_t ov0_graphics_key_msk;    uint32_t ov0_key_cntl;    uint32_t disp_merge_cntl;}saved_regs_t;static saved_regs_t savreg;static void save_regs( void ){    radeon_fifo_wait(6);    savreg.ov0_vid_key_clr	= INREG(OV0_VID_KEY_CLR);    savreg.ov0_vid_key_msk	= INREG(OV0_VID_KEY_MSK);    savreg.ov0_graphics_key_clr = INREG(OV0_GRAPHICS_KEY_CLR);    savreg.ov0_graphics_key_msk = INREG(OV0_GRAPHICS_KEY_MSK);    savreg.ov0_key_cntl		= INREG(OV0_KEY_CNTL);    savreg.disp_merge_cntl	= INREG(DISP_MERGE_CNTL);}static void restore_regs( void ){    radeon_fifo_wait(6);    OUTREG(OV0_VID_KEY_CLR,savreg.ov0_vid_key_clr);    OUTREG(OV0_VID_KEY_MSK,savreg.ov0_vid_key_msk);    OUTREG(OV0_GRAPHICS_KEY_CLR,savreg.ov0_graphics_key_clr);    OUTREG(OV0_GRAPHICS_KEY_MSK,savreg.ov0_graphics_key_msk);    OUTREG(OV0_KEY_CNTL,savreg.ov0_key_cntl);    OUTREG(DISP_MERGE_CNTL,savreg.disp_merge_cntl);}static int radeon_init(void){  int err;  if(__verbose>0) printf("[radeon_vid] version %d\n", VIDIX_VERSION);  if(!probed)   {    printf(RADEON_MSG" Driver was not probed but is being initializing\n");    return EINTR;  }      if((radeon_mmio_base = map_phys_mem(pci_info.base2,0xFFFF))==(void *)-1) return ENOMEM;  radeon_ram_size = INREG(CONFIG_MEMSIZE);  /* mem size is bits [28:0], mask off the rest. Range: from 1Mb up to 512 Mb */  radeon_ram_size &=  CONFIG_MEMSIZE_MASK;#ifdef RADEON  /* according to XFree86 4.2.0, some production M6's return 0 for 8MB */  if (radeon_ram_size == 0 &&      (def_cap.device_id == DEVICE_ATI_RADEON_MOBILITY_M6 ||       def_cap.device_id == DEVICE_ATI_RADEON_MOBILITY_M62))  {      printf(RADEON_MSG" Working around buggy Radeon Mobility M6 (0 vs. 8MB ram)\n");      radeon_ram_size = 8192*1024;  }  else if (radeon_ram_size == 0 &&           (def_cap.device_id == DEVICE_ATI_RS482_RADEON_XPRESS))  {      printf(RADEON_MSG" Working around buggy RS482 Radeon Xpress 200 Memory Detection\n");      radeon_ram_size = (INREG(CONFIG_MEMSIZE) + 0x100000) << 2;      radeon_ram_size &=  CONFIG_MEMSIZE_MASK;  } #else  /* Rage Mobility (rage128) also has memsize bug */  if (radeon_ram_size == 0 &&      (def_cap.device_id == DEVICE_ATI_RAGE_MOBILITY_M3 ||       def_cap.device_id == DEVICE_ATI_RAGE_MOBILITY_M32))  {      printf(RADEON_MSG" Working around Rage Mobility M3 (0 vs. 8MB ram)\n");      radeon_ram_size = 8192*1024;  }#endif  if((radeon_mem_base = map_phys_mem(pci_info.base0,radeon_ram_size))==(void *)-1) return ENOMEM;  radeon_vid_make_default();  printf(RADEON_MSG" Video memory = %uMb\n",radeon_ram_size/0x100000);  err = mtrr_set_type(pci_info.base0,radeon_ram_size,MTRR_TYPE_WRCOMB);  if(!err) printf(RADEON_MSG" Set write-combining type of video memory\n");#ifndef RAGE128  {    memset(&rinfo,0,sizeof(rinfo_t));    if((besr.chip_flags&R_100) != R_100) rinfo.hasCRTC2 = 1;        radeon_get_moninfo(&rinfo);	if(rinfo.hasCRTC2) {	    printf(RADEON_MSG" DVI port has %s monitor connected\n",GET_MON_NAME(rinfo.dviDispType));	    printf(RADEON_MSG" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo.crtDispType));	}	else	    printf(RADEON_MSG" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo.crtDispType));  }#endif  save_regs();  return 0;  }static void radeon_destroy(void){  restore_regs();  unmap_phys_mem(radeon_mem_base,radeon_ram_size);  unmap_phys_mem(radeon_mmio_base,0xFFFF);}static int radeon_get_caps(vidix_capability_t *to){  memcpy(to,&def_cap,sizeof(vidix_capability_t));  return 0; }/*  Full list of fourcc which are supported by Win2K radeon driver:  YUY2, UYVY, DDES, OGLT, OGL2, OGLS, OGLB, OGNT, OGNZ, OGNS,  IF09, YVU9, IMC4, M2IA, IYUV, VBID, DXT1, DXT2, DXT3, DXT4, DXT5*/typedef struct fourcc_desc_s{    uint32_t fourcc;    unsigned max_srcw;}fourcc_desc_t;static fourcc_desc_t supported_fourcc[] = {  { IMGFMT_Y800, 1567 },  { IMGFMT_YVU9, 1567 },  { IMGFMT_IF09, 1567 },  { IMGFMT_YV12, 1567 },  { IMGFMT_I420, 1567 },  { IMGFMT_IYUV, 1567 },   { IMGFMT_UYVY, 1551 },  { IMGFMT_YUY2, 1551 },  { IMGFMT_YVYU, 1551 },  { IMGFMT_RGB15, 1551 },  { IMGFMT_BGR15, 1551 },  { IMGFMT_RGB16, 1551 },  { IMGFMT_BGR16, 1551 },  { IMGFMT_RGB32, 775 },  { IMGFMT_BGR32, 775 }};__inline__ static int is_supported_fourcc(uint32_t fourcc){  unsigned i;  for(i=0;i<sizeof(supported_fourcc)/sizeof(fourcc_desc_t);i++)  {    if(fourcc==supported_fourcc[i].fourcc)      return 1;  }  return 0;}static int radeon_query_fourcc(vidix_fourcc_t *to){    if(is_supported_fourcc(to->fourcc))    {	to->depth = VID_DEPTH_ALL;	to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY |		    VID_CAP_BLEND;	return 0;    }    else  to->depth = to->flags = 0;    return ENOSYS;}static double H_scale_ratio;static void radeon_vid_dump_regs( void ){  size_t i;  printf(RADEON_MSG"*** Begin of DRIVER variables dump ***\n");  printf(RADEON_MSG"radeon_mmio_base=%p\n",radeon_mmio_base);  printf(RADEON_MSG"radeon_mem_base=%p\n",radeon_mem_base);  printf(RADEON_MSG"radeon_overlay_off=%08X\n",radeon_overlay_off);  printf(RADEON_MSG"radeon_ram_size=%08X\n",radeon_ram_size);  printf(RADEON_MSG"video mode: %ux%u@%u\n",radeon_get_xres(),radeon_get_yres(),radeon_vid_get_dbpp());  printf(RADEON_MSG"H_scale_ratio=%8.2f\n",H_scale_ratio);  printf(RADEON_MSG"*** Begin of OV0 registers dump ***\n");  for(i=0;i<sizeof(vregs)/sizeof(video_registers_t);i++)	printf(RADEON_MSG"%s = %08X\n",vregs[i].sname,INREG(vregs[i].name));  printf(RADEON_MSG"*** End of OV0 registers dump ***\n");}static void radeon_vid_stop_video( void ){    radeon_engine_idle();    OUTREG(OV0_SCALE_CNTL, SCALER_SOFT_RESET);    OUTREG(OV0_EXCLUSIVE_HORZ, 0);    OUTREG(OV0_AUTO_FLIP_CNTL, 0);   /* maybe */    OUTREG(OV0_FILTER_CNTL, FILTER_HARDCODED_COEF);#ifdef RAGE128        OUTREG(OV0_KEY_CNTL, GRAPHIC_KEY_FN_NE);#else    OUTREG(OV0_KEY_CNTL, GRAPHIC_KEY_FN_EQ);#endif    OUTREG(OV0_TEST, 0);}static void radeon_vid_display_video( void ){    int bes_flags,force_second;    radeon_fifo_wait(2);    OUTREG(OV0_REG_LOAD_CNTL,		REG_LD_CTL_LOCK);    radeon_engine_idle();    while(!(INREG(OV0_REG_LOAD_CNTL)&REG_LD_CTL_LOCK_READBACK));    radeon_fifo_wait(15);    force_second=0;    /* Shutdown capturing */    OUTREG(FCP_CNTL, FCP_CNTL__GND);    OUTREG(CAP0_TRIG_CNTL, 0);    OUTREG(VID_BUFFER_CONTROL, (1<<16) | 0x01);    OUTREG(DISP_TEST_DEBUG_CNTL, 0);    OUTREG(OV0_AUTO_FLIP_CNTL,OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD);    if(besr.deinterlace_on) OUTREG(OV0_DEINTERLACE_PATTERN,besr.deinterlace_pattern);#ifdef RAGE128    OUTREG(OV0_COLOUR_CNTL, (besr.brightness & 0x7f) |			    (besr.saturation << 8) |			    (besr.saturation << 16));#endif    radeon_fifo_wait(2);    OUTREG(OV0_GRAPHICS_KEY_MSK, besr.graphics_key_msk);    OUTREG(OV0_GRAPHICS_KEY_CLR, besr.graphics_key_clr);    OUTREG(OV0_KEY_CNTL,besr.ckey_cntl);    OUTREG(OV0_H_INC,			besr.h_inc);    OUTREG(OV0_STEP_BY,			besr.step_by);    if(force_second)    {	OUTREG(OV1_Y_X_START,		besr.y_x_start);	OUTREG(OV1_Y_X_END,		besr.y_x_end);    }    else    {	OUTREG(OV0_Y_X_START,		besr.y_x_start);	OUTREG(OV0_Y_X_END,		besr.y_x_end);    }    OUTREG(OV0_V_INC,			besr.v_inc);    OUTREG(OV0_P1_BLANK_LINES_AT_TOP,	besr.p1_blank_lines_at_top);    OUTREG(OV0_P23_BLANK_LINES_AT_TOP,	besr.p23_blank_lines_at_top);    OUTREG(OV0_VID_BUF_PITCH0_VALUE,	besr.vid_buf_pitch0_value);    OUTREG(OV0_VID_BUF_PITCH1_VALUE,	besr.vid_buf_pitch1_value);    OUTREG(OV0_P1_X_START_END,		besr.p1_x_start_end);    OUTREG(OV0_P2_X_START_END,		besr.p2_x_start_end);    OUTREG(OV0_P3_X_START_END,		besr.p3_x_start_end);#ifdef RADEON    OUTREG(OV0_BASE_ADDR,		besr.base_addr);#endif    OUTREG(OV0_VID_BUF0_BASE_ADRS,	besr.vid_buf_base_adrs_y[0]);    OUTREG(OV0_VID_BUF1_BASE_ADRS,	besr.vid_buf_base_adrs_v[0]);    OUTREG(OV0_VID_BUF2_BASE_ADRS,	besr.vid_buf_base_adrs_u[0]);    radeon_fifo_wait(9);    OUTREG(OV0_VID_BUF3_BASE_ADRS,	besr.vid_buf_base_adrs_y[0]);    OUTREG(OV0_VID_BUF4_BASE_ADRS,	besr.vid_buf_base_adrs_v[0]);    OUTREG(OV0_VID_BUF5_BASE_ADRS,	besr.vid_buf_base_adrs_u[0]);    OUTREG(OV0_P1_V_ACCUM_INIT,		besr.p1_v_accum_init);    OUTREG(OV0_P1_H_ACCUM_INIT,		besr.p1_h_accum_init);    OUTREG(OV0_P23_H_ACCUM_INIT,	besr.p23_h_accum_init);    OUTREG(OV0_P23_V_ACCUM_INIT,	besr.p23_v_accum_init);    bes_flags = SCALER_ENABLE |		SCALER_SMART_SWITCH |		SCALER_Y2R_TEMP |		SCALER_PIX_EXPAND;    if(besr.double_buff) bes_flags |= SCALER_DOUBLE_BUFFER;    if(besr.deinterlace_on) bes_flags |= SCALER_ADAPTIVE_DEINT;    if(besr.horz_pick_nearest) bes_flags |= SCALER_HORZ_PICK_NEAREST;    if(besr.vert_pick_nearest) bes_flags |= SCALER_VERT_PICK_NEAREST;#ifdef RAGE128    bes_flags |= SCALER_BURST_PER_PLANE;#endif    bes_flags |= (besr.surf_id << 8) & SCALER_SURFAC_FORMAT;    if(besr.load_prg_start) bes_flags |= SCALER_PRG_LOAD_START;    if(force_second)	bes_flags |= SCALER_USE_OV1;    else		bes_flags &= ~SCALER_USE_OV1;    OUTREG(OV0_SCALE_CNTL,		bes_flags);    radeon_fifo_wait(6);    OUTREG(OV0_FILTER_CNTL,besr.filter_cntl);    OUTREG(OV0_FOUR_TAP_COEF_0,besr.four_tap_coeff[0]);    OUTREG(OV0_FOUR_TAP_COEF_1,besr.four_tap_coeff[1]);    OUTREG(OV0_FOUR_TAP_COEF_2,besr.four_tap_coeff[2]);    OUTREG(OV0_FOUR_TAP_COEF_3,besr.four_tap_coeff[3]);    OUTREG(OV0_FOUR_TAP_COEF_4,besr.four_tap_coeff[4]);    if(besr.swap_uv) OUTREG(OV0_TEST,INREG(OV0_TEST)|OV0_SWAP_UV);    OUTREG(OV0_REG_LOAD_CNTL,		0);    if(__verbose > VERBOSE_LEVEL) printf(RADEON_MSG"we wanted: scaler=%08X\n",bes_flags);    if(__verbose > VERBOSE_LEVEL) radeon_vid_dump_regs();}/* Goal of this function: hide RGB background and provide black screen around movie.   Useful in '-vo fbdev:vidix -fs -zoom' mode.   Reverse effect to colorkey */#ifdef RAGE128static void radeon_vid_exclusive( void ){/* this function works only with Rage128.   Radeon should has something the same */    unsigned screenw,screenh;    screenw = radeon_get_xres();    screenh = radeon_get_yres();    radeon_fifo_wait(2);    OUTREG(OV0_EXCLUSIVE_VERT,(((screenh-1)<<16)&EXCL_VERT_END_MASK));    OUTREG(OV0_EXCLUSIVE_HORZ,(((screenw/8+1)<<8)&EXCL_HORZ_END_MASK)|EXCL_HORZ_EXCLUSIVE_EN);}static void radeon_vid_non_exclusive( void ){

⌨️ 快捷键说明

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