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)®_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 + -
显示快捷键?