Mercurial > mplayer.hg
annotate vidix/mach64_vid.c @ 25317:7f3cb5408f28
Fixed VIDIX color bug that was introduced when Radeon VIDIX driver
was synchronized with vidix.sf.net.
The red color was saturating.
Corrected value fixes the issue and restore the color to the level
it used to have before synchronization.
Meaning of the value remains unknow but was retrieved from
register's value of a Radeon 9000 card, so it may need further testing.
Patch by Guillaume Lecerf (foxcore at gmail dot com)
author | ben |
---|---|
date | Mon, 10 Dec 2007 19:27:46 +0000 |
parents | b451fd2b2520 |
children | e8af7338a462 |
rev | line source |
---|---|
22850 | 1 /* |
23046
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
2 * VIDIX driver for ATI Mach64 and 3DRage chipsets. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
3 * Copyright (C) 2002 Nick Kurshev |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
4 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
5 * This file is part of MPlayer. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
6 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
7 * MPlayer is free software; you can redistribute it and/or modify |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
8 * it under the terms of the GNU General Public License as published by |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
9 * the Free Software Foundation; either version 2 of the License, or |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
10 * (at your option) any later version. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
11 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
12 * MPlayer is distributed in the hope that it will be useful, |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
15 * GNU General Public License for more details. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
16 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
17 * You should have received a copy of the GNU General Public License |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
18 * along with MPlayer; if not, write to the Free Software |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
20 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
21 * This file is based on sources from |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
22 * GATOS (gatos.sf.net) and X11 (www.xfree86.org) |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
23 */ |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
24 |
22850 | 25 #include <errno.h> |
26 #include <stdio.h> | |
27 #include <stdlib.h> | |
28 #include <string.h> | |
29 #include <math.h> | |
30 #include <inttypes.h> | |
31 #include <fcntl.h> | |
32 | |
22905 | 33 #include "config.h" |
34 #include "libavutil/common.h" | |
35 #include "mpbswap.h" | |
22850 | 36 #include "vidix.h" |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
37 #include "vidixlib.h" |
22850 | 38 #include "fourcc.h" |
22901 | 39 #include "dha.h" |
22900
a9e111b88c4a
merged libdha and libvidix, moved all files from libdha to vidix directory
ben
parents:
22858
diff
changeset
|
40 #include "pci_ids.h" |
a9e111b88c4a
merged libdha and libvidix, moved all files from libdha to vidix directory
ben
parents:
22858
diff
changeset
|
41 #include "pci_names.h" |
22850 | 42 |
43 #include "mach64.h" | |
44 | |
45 #define UNUSED(x) ((void)(x)) /**< Removes warning about unused arguments */ | |
46 | |
47 static void *mach64_mmio_base = 0; | |
48 static void *mach64_mem_base = 0; | |
49 static int32_t mach64_overlay_offset = 0; | |
50 static uint32_t mach64_ram_size = 0; | |
51 static uint32_t mach64_buffer_base[10][3]; | |
52 static int num_mach64_buffers=-1; | |
53 static int supports_planar=0; | |
54 static int supports_lcd_v_stretch=0; | |
55 | |
23053 | 56 static pciinfo_t pci_info; |
22850 | 57 static int probed = 0; |
58 static int __verbose = 0; | |
59 | |
60 #define VERBOSE_LEVEL 1 | |
61 | |
62 typedef struct bes_registers_s | |
63 { | |
64 /* base address of yuv framebuffer */ | |
65 uint32_t yuv_base; | |
66 uint32_t fourcc; | |
67 /* YUV BES registers */ | |
68 uint32_t reg_load_cntl; | |
69 uint32_t scale_inc; | |
70 uint32_t y_x_start; | |
71 uint32_t y_x_end; | |
72 uint32_t vid_buf_pitch; | |
73 uint32_t height_width; | |
74 | |
75 uint32_t scale_cntl; | |
76 uint32_t exclusive_horz; | |
77 uint32_t auto_flip_cntl; | |
78 uint32_t filter_cntl; | |
79 uint32_t key_cntl; | |
80 uint32_t test; | |
81 /* Configurable stuff */ | |
82 | |
83 int brightness; | |
84 int saturation; | |
85 | |
86 int ckey_on; | |
87 uint32_t graphics_key_clr; | |
88 uint32_t graphics_key_msk; | |
89 | |
90 int deinterlace_on; | |
91 uint32_t deinterlace_pattern; | |
92 | |
93 } bes_registers_t; | |
94 | |
95 static bes_registers_t besr; | |
96 | |
97 typedef struct video_registers_s | |
98 { | |
99 const char * sname; | |
100 uint32_t name; | |
101 uint32_t value; | |
102 }video_registers_t; | |
103 | |
104 /* Graphic keys */ | |
105 static vidix_grkey_t mach64_grkey; | |
106 | |
107 #define DECLARE_VREG(name) { #name, name, 0 } | |
108 static video_registers_t vregs[] = | |
109 { | |
110 DECLARE_VREG(OVERLAY_SCALE_INC), | |
111 DECLARE_VREG(OVERLAY_Y_X_START), | |
112 DECLARE_VREG(OVERLAY_Y_X_END), | |
113 DECLARE_VREG(OVERLAY_SCALE_CNTL), | |
114 DECLARE_VREG(OVERLAY_EXCLUSIVE_HORZ), | |
115 DECLARE_VREG(OVERLAY_EXCLUSIVE_VERT), | |
116 DECLARE_VREG(OVERLAY_TEST), | |
117 DECLARE_VREG(SCALER_BUF_PITCH), | |
118 DECLARE_VREG(SCALER_HEIGHT_WIDTH), | |
119 DECLARE_VREG(SCALER_BUF0_OFFSET), | |
120 DECLARE_VREG(SCALER_BUF0_OFFSET_U), | |
121 DECLARE_VREG(SCALER_BUF0_OFFSET_V), | |
122 DECLARE_VREG(SCALER_BUF1_OFFSET), | |
123 DECLARE_VREG(SCALER_BUF1_OFFSET_U), | |
124 DECLARE_VREG(SCALER_BUF1_OFFSET_V), | |
125 DECLARE_VREG(SCALER_H_COEFF0), | |
126 DECLARE_VREG(SCALER_H_COEFF1), | |
127 DECLARE_VREG(SCALER_H_COEFF2), | |
128 DECLARE_VREG(SCALER_H_COEFF3), | |
129 DECLARE_VREG(SCALER_H_COEFF4), | |
130 DECLARE_VREG(SCALER_COLOUR_CNTL), | |
131 DECLARE_VREG(SCALER_THRESHOLD), | |
132 DECLARE_VREG(VIDEO_FORMAT), | |
133 DECLARE_VREG(VIDEO_CONFIG), | |
134 DECLARE_VREG(VIDEO_SYNC_TEST), | |
135 DECLARE_VREG(VIDEO_SYNC_TEST_B) | |
136 }; | |
137 | |
138 /* have to restore it on exit */ | |
139 static uint32_t SAVED_OVERLAY_GRAPHICS_KEY_CLR; | |
140 | |
141 /* VIDIX exports */ | |
142 | |
143 /* MMIO space*/ | |
144 #define GETREG(TYPE,PTR,OFFZ) (*((volatile TYPE*)((PTR)+(OFFZ)))) | |
145 #define SETREG(TYPE,PTR,OFFZ,VAL) (*((volatile TYPE*)((PTR)+(OFFZ))))=VAL | |
146 | |
147 #define INREG8(addr) GETREG(uint8_t,(uint8_t *)mach64_mmio_base,((addr)^0x100)<<2) | |
148 #define OUTREG8(addr,val) SETREG(uint8_t,(uint8_t *)mach64_mmio_base,((addr)^0x100)<<2,val) | |
149 | |
150 static inline uint32_t INREG (uint32_t addr) { | |
151 uint32_t tmp = GETREG(uint32_t,(uint8_t *)mach64_mmio_base,((addr)^0x100)<<2); | |
152 return le2me_32(tmp); | |
153 } | |
154 #define OUTREG(addr,val) SETREG(uint32_t,(uint8_t *)mach64_mmio_base,((addr)^0x100)<<2,le2me_32(val)) | |
155 | |
156 #define OUTREGP(addr,val,mask) \ | |
157 do { \ | |
158 unsigned int _tmp = INREG(addr); \ | |
159 _tmp &= (mask); \ | |
160 _tmp |= (val); \ | |
161 OUTREG(addr, _tmp); \ | |
162 } while (0) | |
163 | |
164 static __inline__ int ATIGetMach64LCDReg(int _Index) | |
165 { | |
166 OUTREG8(LCD_INDEX, _Index); | |
167 return INREG(LCD_DATA); | |
168 } | |
169 | |
170 static __inline__ uint32_t INPLL(uint32_t addr) | |
171 { | |
172 uint32_t res; | |
173 uint32_t in; | |
174 | |
175 in= INREG(CLOCK_CNTL); | |
176 in &= ~((PLL_WR_EN | PLL_ADDR)); //clean some stuff | |
177 OUTREG(CLOCK_CNTL, in | (addr<<10)); | |
178 | |
179 /* read the register value */ | |
180 res = (INREG(CLOCK_CNTL)>>16)&0xFF; | |
181 return res; | |
182 } | |
183 | |
184 static __inline__ void OUTPLL(uint32_t addr,uint32_t val) | |
185 { | |
186 //FIXME buggy but its not used | |
187 /* write addr byte */ | |
188 OUTREG8(CLOCK_CNTL + 1, (addr << 2) | PLL_WR_EN); | |
189 /* write the register value */ | |
190 OUTREG(CLOCK_CNTL + 2, val); | |
191 OUTREG8(CLOCK_CNTL + 1, (addr << 2) & ~PLL_WR_EN); | |
192 } | |
193 | |
194 #define OUTPLLP(addr,val,mask) \ | |
195 do { \ | |
196 unsigned int _tmp = INPLL(addr); \ | |
197 _tmp &= (mask); \ | |
198 _tmp |= (val); \ | |
199 OUTPLL(addr, _tmp); \ | |
200 } while (0) | |
201 | |
202 static void mach64_fifo_wait(unsigned n) | |
203 { | |
204 while ((INREG(FIFO_STAT) & 0xffff) > ((uint32_t)(0x8000 >> n))); | |
205 } | |
206 | |
207 static void mach64_wait_for_idle( void ) | |
208 { | |
209 mach64_fifo_wait(16); | |
210 while ((INREG(GUI_STAT) & 1)!= 0); | |
211 } | |
212 | |
213 static void mach64_wait_vsync( void ) | |
214 { | |
215 int i; | |
216 | |
217 for(i=0; i<2000000; i++) | |
218 if( (INREG(CRTC_INT_CNTL)&CRTC_VBLANK)==0 ) break; | |
219 for(i=0; i<2000000; i++) | |
220 if( (INREG(CRTC_INT_CNTL)&CRTC_VBLANK) ) break; | |
221 | |
222 } | |
223 | |
224 static vidix_capability_t mach64_cap = | |
225 { | |
226 "BES driver for Mach64/3DRage cards", | |
227 "Nick Kurshev and Michael Niedermayer", | |
228 TYPE_OUTPUT, | |
229 { 0, 0, 0, 0 }, | |
230 2048, | |
231 2048, | |
232 4, | |
233 4, | |
234 -1, | |
235 FLAG_UPSCALER|FLAG_DOWNSCALER, | |
236 VENDOR_ATI, | |
237 -1, | |
238 { 0, 0, 0, 0 } | |
239 }; | |
240 | |
241 static uint32_t mach64_vid_get_dbpp( void ) | |
242 { | |
243 uint32_t dbpp,retval; | |
244 dbpp = (INREG(CRTC_GEN_CNTL)>>8)& 0x7; | |
245 switch(dbpp) | |
246 { | |
247 case 1: retval = 4; break; | |
248 case 2: retval = 8; break; | |
249 case 3: retval = 15; break; | |
250 case 4: retval = 16; break; | |
251 case 5: retval = 24; break; | |
252 default: retval=32; break; | |
253 } | |
254 return retval; | |
255 } | |
256 | |
257 static int mach64_is_dbl_scan( void ) | |
258 { | |
259 return INREG(CRTC_GEN_CNTL) & CRTC_DBL_SCAN_EN; | |
260 } | |
261 | |
262 static int mach64_is_interlace( void ) | |
263 { | |
264 return INREG(CRTC_GEN_CNTL) & CRTC_INTERLACE_EN; | |
265 } | |
266 | |
267 static uint32_t mach64_get_xres( void ) | |
268 { | |
269 /* FIXME: currently we extract that from CRTC!!!*/ | |
270 uint32_t xres,h_total; | |
271 h_total = INREG(CRTC_H_TOTAL_DISP); | |
272 xres = (h_total >> 16) & 0xffff; | |
273 return (xres + 1)*8; | |
274 } | |
275 | |
276 static uint32_t mach64_get_yres( void ) | |
277 { | |
278 /* FIXME: currently we extract that from CRTC!!!*/ | |
279 uint32_t yres,v_total; | |
280 v_total = INREG(CRTC_V_TOTAL_DISP); | |
281 yres = (v_total >> 16) & 0xffff; | |
282 return yres + 1; | |
283 } | |
284 | |
285 // returns the verical stretch factor in 16.16 | |
286 static int mach64_get_vert_stretch(void) | |
287 { | |
288 int lcd_index; | |
289 int vert_stretching; | |
290 int ext_vert_stretch; | |
291 int ret; | |
292 int yres= mach64_get_yres(); | |
293 | |
294 if(!supports_lcd_v_stretch){ | |
295 if(__verbose>0) printf("[mach64] vertical stretching not supported\n"); | |
296 return 1<<16; | |
297 } | |
298 | |
299 lcd_index= INREG(LCD_INDEX); | |
300 | |
301 vert_stretching= ATIGetMach64LCDReg(LCD_VERT_STRETCHING); | |
302 if(!(vert_stretching&VERT_STRETCH_EN)) ret= 1<<16; | |
303 else | |
304 { | |
305 int panel_size; | |
306 | |
307 ext_vert_stretch= ATIGetMach64LCDReg(LCD_EXT_VERT_STRETCH); | |
308 panel_size= (ext_vert_stretch&VERT_PANEL_SIZE)>>11; | |
309 panel_size++; | |
310 | |
311 ret= ((yres<<16) + (panel_size>>1))/panel_size; | |
312 } | |
313 | |
314 // lcd_gen_ctrl = ATIGetMach64LCDReg(LCD_GEN_CNTL); | |
315 | |
316 OUTREG(LCD_INDEX, lcd_index); | |
317 | |
318 if(__verbose>0) printf("[mach64] vertical stretching factor= %d\n", ret); | |
319 | |
320 return ret; | |
321 } | |
322 | |
323 static void mach64_vid_make_default(void) | |
324 { | |
325 mach64_fifo_wait(5); | |
326 OUTREG(SCALER_COLOUR_CNTL,0x00101000); | |
327 | |
328 besr.ckey_on=0; | |
329 besr.graphics_key_msk=0; | |
330 besr.graphics_key_clr=0; | |
331 | |
332 OUTREG(OVERLAY_GRAPHICS_KEY_MSK, besr.graphics_key_msk); | |
333 OUTREG(OVERLAY_GRAPHICS_KEY_CLR, besr.graphics_key_clr); | |
334 OUTREG(OVERLAY_KEY_CNTL,VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_EQ|CMP_MIX_AND); | |
335 | |
336 } | |
337 | |
338 static void mach64_vid_dump_regs( void ) | |
339 { | |
340 size_t i; | |
341 printf("[mach64] *** Begin of DRIVER variables dump ***\n"); | |
342 printf("[mach64] mach64_mmio_base=%p\n",mach64_mmio_base); | |
343 printf("[mach64] mach64_mem_base=%p\n",mach64_mem_base); | |
344 printf("[mach64] mach64_overlay_off=%08X\n",mach64_overlay_offset); | |
345 printf("[mach64] mach64_ram_size=%08X\n",mach64_ram_size); | |
346 printf("[mach64] video mode: %ux%u@%u\n",mach64_get_xres(),mach64_get_yres(),mach64_vid_get_dbpp()); | |
347 printf("[mach64] *** Begin of OV0 registers dump ***\n"); | |
348 for(i=0;i<sizeof(vregs)/sizeof(video_registers_t);i++) | |
349 { | |
350 mach64_wait_for_idle(); | |
351 printf("[mach64] %s = %08X\n",vregs[i].sname,INREG(vregs[i].name)); | |
352 } | |
353 printf("[mach64] *** End of OV0 registers dump ***\n"); | |
354 } | |
355 | |
356 | |
357 static unsigned short ati_card_ids[] = | |
358 { | |
359 DEVICE_ATI_215CT_MACH64_CT, | |
360 DEVICE_ATI_210888CX_MACH64_CX, | |
361 DEVICE_ATI_210888ET_MACH64_ET, | |
362 DEVICE_ATI_MACH64_VT, | |
363 DEVICE_ATI_210888GX_MACH64_GX, | |
364 DEVICE_ATI_264LT_MACH64_LT, | |
365 DEVICE_ATI_264VT_MACH64_VT, | |
366 DEVICE_ATI_264VT3_MACH64_VT3, | |
367 DEVICE_ATI_264VT4_MACH64_VT4, | |
368 /**/ | |
369 DEVICE_ATI_3D_RAGE_PRO, | |
370 DEVICE_ATI_3D_RAGE_PRO2, | |
371 DEVICE_ATI_3D_RAGE_PRO3, | |
372 DEVICE_ATI_3D_RAGE_PRO4, | |
373 DEVICE_ATI_RAGE_XC, | |
374 DEVICE_ATI_RAGE_XL_AGP, | |
375 DEVICE_ATI_RAGE_XC_AGP, | |
376 DEVICE_ATI_RAGE_XL, | |
377 DEVICE_ATI_3D_RAGE_PRO5, | |
378 DEVICE_ATI_3D_RAGE_PRO6, | |
379 DEVICE_ATI_RAGE_XL2, | |
380 DEVICE_ATI_RAGE_XC2, | |
381 DEVICE_ATI_3D_RAGE_I_II, | |
382 DEVICE_ATI_3D_RAGE_II, | |
383 DEVICE_ATI_3D_RAGE_IIC, | |
384 DEVICE_ATI_3D_RAGE_IIC2, | |
385 DEVICE_ATI_3D_RAGE_IIC3, | |
386 DEVICE_ATI_3D_RAGE_IIC4, | |
387 DEVICE_ATI_3D_RAGE_LT, | |
388 DEVICE_ATI_3D_RAGE_LT2, | |
389 DEVICE_ATI_3D_RAGE_LT_G, | |
390 DEVICE_ATI_3D_RAGE_LT3, | |
391 DEVICE_ATI_RAGE_MOBILITY_P_M, | |
392 DEVICE_ATI_RAGE_MOBILITY_L, | |
393 DEVICE_ATI_3D_RAGE_LT4, | |
394 DEVICE_ATI_3D_RAGE_LT5, | |
395 DEVICE_ATI_RAGE_MOBILITY_P_M2, | |
396 DEVICE_ATI_RAGE_MOBILITY_L2 | |
397 }; | |
398 | |
399 static int find_chip(unsigned chip_id) | |
400 { | |
401 unsigned i; | |
402 for(i = 0;i < sizeof(ati_card_ids)/sizeof(unsigned short);i++) | |
403 { | |
404 if(chip_id == ati_card_ids[i]) return i; | |
405 } | |
406 return -1; | |
407 } | |
408 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
409 static int mach64_probe(int verbose,int force) |
22850 | 410 { |
411 pciinfo_t lst[MAX_PCI_DEVICES]; | |
412 unsigned i,num_pci; | |
413 int err; | |
414 __verbose = verbose; | |
415 err = pci_scan(lst,&num_pci); | |
416 if(err) | |
417 { | |
418 printf("[mach64] Error occurred during pci scan: %s\n",strerror(err)); | |
419 return err; | |
420 } | |
421 else | |
422 { | |
423 err = ENXIO; | |
424 for(i=0;i<num_pci;i++) | |
425 { | |
426 if(lst[i].vendor == VENDOR_ATI) | |
427 { | |
428 int idx; | |
429 const char *dname; | |
430 idx = find_chip(lst[i].device); | |
431 if(idx == -1 && force == PROBE_NORMAL) continue; | |
432 dname = pci_device_name(VENDOR_ATI,lst[i].device); | |
433 dname = dname ? dname : "Unknown chip"; | |
434 printf("[mach64] Found chip: %s\n",dname); | |
23167
2ab3eac7f6da
synced with upstream vidix, prevented some drivers to work on some configs/archs
ben
parents:
23060
diff
changeset
|
435 #if 0 |
22850 | 436 if ((lst[i].command & PCI_COMMAND_IO) == 0) |
437 { | |
438 printf("[mach64] Device is disabled, ignoring\n"); | |
439 continue; | |
440 } | |
23167
2ab3eac7f6da
synced with upstream vidix, prevented some drivers to work on some configs/archs
ben
parents:
23060
diff
changeset
|
441 #endif |
22850 | 442 if(force > PROBE_NORMAL) |
443 { | |
444 printf("[mach64] Driver was forced. Was found %sknown chip\n",idx == -1 ? "un" : ""); | |
445 if(idx == -1) | |
446 printf("[mach64] Assuming it as Mach64\n"); | |
447 } | |
448 mach64_cap.device_id = lst[i].device; | |
449 err = 0; | |
450 memcpy(&pci_info,&lst[i],sizeof(pciinfo_t)); | |
451 probed=1; | |
452 break; | |
453 } | |
454 } | |
455 } | |
456 if(err && verbose) printf("[mach64] Can't find chip\n"); | |
457 return err; | |
458 } | |
459 | |
460 static void reset_regs( void ) | |
461 { | |
462 size_t i; | |
463 for(i=0;i<sizeof(vregs)/sizeof(video_registers_t);i++) | |
464 { | |
465 mach64_fifo_wait(2); | |
466 OUTREG(vregs[i].name,0); | |
467 } | |
468 } | |
469 | |
470 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
471 static int mach64_init(void) |
22850 | 472 { |
473 int err; | |
474 if(!probed) | |
475 { | |
476 printf("[mach64] Driver was not probed but is being initializing\n"); | |
477 return EINTR; | |
478 } | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
479 if(__verbose>0) printf("[mach64] version %d\n", VIDIX_VERSION); |
22850 | 480 |
481 if((mach64_mmio_base = map_phys_mem(pci_info.base2,0x1000))==(void *)-1) return ENOMEM; | |
482 mach64_wait_for_idle(); | |
483 mach64_ram_size = INREG(MEM_CNTL) & CTL_MEM_SIZEB; | |
484 if (mach64_ram_size < 8) mach64_ram_size = (mach64_ram_size + 1) * 512; | |
485 else if (mach64_ram_size < 12) mach64_ram_size = (mach64_ram_size - 3) * 1024; | |
486 else mach64_ram_size = (mach64_ram_size - 7) * 2048; | |
487 mach64_ram_size *= 0x400; /* KB -> bytes */ | |
488 if((mach64_mem_base = map_phys_mem(pci_info.base0,mach64_ram_size))==(void *)-1) return ENOMEM; | |
489 memset(&besr,0,sizeof(bes_registers_t)); | |
490 printf("[mach64] Video memory = %uMb\n",mach64_ram_size/0x100000); | |
491 err = mtrr_set_type(pci_info.base0,mach64_ram_size,MTRR_TYPE_WRCOMB); | |
492 if(!err) printf("[mach64] Set write-combining type of video memory\n"); | |
493 | |
494 /* save this */ | |
495 mach64_wait_for_idle(); | |
496 SAVED_OVERLAY_GRAPHICS_KEY_CLR = INREG(OVERLAY_GRAPHICS_KEY_CLR); | |
497 | |
498 /* check if planar formats are supported */ | |
499 supports_planar=0; | |
500 mach64_wait_for_idle(); | |
501 mach64_fifo_wait(2); | |
502 if(INREG(SCALER_BUF0_OFFSET_U)) supports_planar=1; | |
503 else | |
504 { | |
505 OUTREG(SCALER_BUF0_OFFSET_U, -1); | |
506 | |
507 mach64_wait_vsync(); | |
508 mach64_wait_for_idle(); | |
509 mach64_fifo_wait(2); | |
510 | |
511 if(INREG(SCALER_BUF0_OFFSET_U)) supports_planar=1; | |
512 } | |
513 if(supports_planar) printf("[mach64] Planar YUV formats are supported :)\n"); | |
514 else printf("[mach64] Planar YUV formats are not supported :(\n"); | |
515 | |
516 if( mach64_cap.device_id==DEVICE_ATI_RAGE_MOBILITY_P_M | |
517 || mach64_cap.device_id==DEVICE_ATI_RAGE_MOBILITY_P_M2 | |
518 || mach64_cap.device_id==DEVICE_ATI_RAGE_MOBILITY_L | |
519 || mach64_cap.device_id==DEVICE_ATI_RAGE_MOBILITY_L2) | |
520 supports_lcd_v_stretch=1; | |
521 else | |
522 supports_lcd_v_stretch=0; | |
523 | |
524 reset_regs(); | |
525 mach64_vid_make_default(); | |
526 | |
527 if(__verbose > VERBOSE_LEVEL) mach64_vid_dump_regs(); | |
528 return 0; | |
529 } | |
530 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
531 static void mach64_destroy(void) |
22850 | 532 { |
533 /*restore this*/ | |
534 mach64_wait_for_idle(); | |
535 OUTREG(OVERLAY_GRAPHICS_KEY_CLR,SAVED_OVERLAY_GRAPHICS_KEY_CLR); | |
536 | |
537 unmap_phys_mem(mach64_mem_base,mach64_ram_size); | |
538 unmap_phys_mem(mach64_mmio_base,0x1000); | |
539 } | |
540 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
541 static int mach64_get_caps(vidix_capability_t *to) |
22850 | 542 { |
543 memcpy(to, &mach64_cap, sizeof(vidix_capability_t)); | |
544 return 0; | |
545 } | |
546 | |
547 static unsigned mach64_query_pitch(unsigned fourcc,const vidix_yuv_t *spitch) | |
548 { | |
549 unsigned pitch,spy,spv,spu; | |
550 spy = spv = spu = 0; | |
551 switch(spitch->y) | |
552 { | |
553 case 16: | |
554 case 32: | |
555 case 64: | |
556 case 128: | |
557 case 256: spy = spitch->y; break; | |
558 default: break; | |
559 } | |
560 switch(spitch->u) | |
561 { | |
562 case 16: | |
563 case 32: | |
564 case 64: | |
565 case 128: | |
566 case 256: spu = spitch->u; break; | |
567 default: break; | |
568 } | |
569 switch(spitch->v) | |
570 { | |
571 case 16: | |
572 case 32: | |
573 case 64: | |
574 case 128: | |
575 case 256: spv = spitch->v; break; | |
576 default: break; | |
577 } | |
578 switch(fourcc) | |
579 { | |
580 /* 4:2:0 */ | |
581 case IMGFMT_IYUV: | |
582 case IMGFMT_YV12: | |
583 case IMGFMT_I420: | |
584 if(spy > 16 && spu == spy/2 && spv == spy/2) pitch = spy; | |
585 else pitch = 32; | |
586 break; | |
587 case IMGFMT_YVU9: | |
588 if(spy > 32 && spu == spy/4 && spv == spy/4) pitch = spy; | |
589 else pitch = 64; | |
590 break; | |
591 default: | |
592 if(spy >= 16) pitch = spy; | |
593 else pitch = 16; | |
594 break; | |
595 } | |
596 return pitch; | |
597 } | |
598 | |
599 static void mach64_compute_framesize(vidix_playback_t *info) | |
600 { | |
601 unsigned pitch,awidth; | |
602 pitch = mach64_query_pitch(info->fourcc,&info->src.pitch); | |
603 switch(info->fourcc) | |
604 { | |
605 case IMGFMT_I420: | |
606 case IMGFMT_YV12: | |
607 case IMGFMT_IYUV: | |
608 awidth = (info->src.w + (pitch-1)) & ~(pitch-1); | |
609 info->frame_size = awidth*(info->src.h+info->src.h/2); | |
610 break; | |
611 case IMGFMT_YVU9: | |
612 awidth = (info->src.w + (pitch-1)) & ~(pitch-1); | |
613 info->frame_size = awidth*(info->src.h+info->src.h/8); | |
614 break; | |
615 // case IMGFMT_RGB32: | |
616 case IMGFMT_BGR32: | |
617 awidth = (info->src.w*4 + (pitch-1)) & ~(pitch-1); | |
618 info->frame_size = (awidth*info->src.h); | |
619 break; | |
620 /* YUY2 YVYU, RGB15, RGB16 */ | |
621 default: | |
622 awidth = (info->src.w*2 + (pitch-1)) & ~(pitch-1); | |
623 info->frame_size = (awidth*info->src.h); | |
624 break; | |
625 } | |
626 info->frame_size+=256; // so we have some space for alignment & such | |
627 info->frame_size&=~16; | |
628 } | |
629 | |
630 static void mach64_vid_stop_video( void ) | |
631 { | |
632 mach64_fifo_wait(14); | |
633 OUTREG(OVERLAY_SCALE_CNTL, 0x80000000); | |
634 OUTREG(OVERLAY_EXCLUSIVE_HORZ, 0); | |
635 OUTREG(OVERLAY_EXCLUSIVE_VERT, 0); | |
636 OUTREG(SCALER_H_COEFF0, 0x00002000); | |
637 OUTREG(SCALER_H_COEFF1, 0x0D06200D); | |
638 OUTREG(SCALER_H_COEFF2, 0x0D0A1C0D); | |
639 OUTREG(SCALER_H_COEFF3, 0x0C0E1A0C); | |
640 OUTREG(SCALER_H_COEFF4, 0x0C14140C); | |
641 OUTREG(VIDEO_FORMAT, 0xB000B); | |
642 OUTREG(OVERLAY_TEST, 0x0); | |
643 } | |
644 | |
645 static void mach64_vid_display_video( void ) | |
646 { | |
647 uint32_t vf; | |
648 mach64_fifo_wait(14); | |
649 | |
650 OUTREG(OVERLAY_Y_X_START, besr.y_x_start); | |
651 OUTREG(OVERLAY_Y_X_END, besr.y_x_end); | |
652 OUTREG(OVERLAY_SCALE_INC, besr.scale_inc); | |
653 OUTREG(SCALER_BUF_PITCH, besr.vid_buf_pitch); | |
654 OUTREG(SCALER_HEIGHT_WIDTH, besr.height_width); | |
655 OUTREG(SCALER_BUF0_OFFSET, mach64_buffer_base[0][0]); | |
656 OUTREG(SCALER_BUF0_OFFSET_U, mach64_buffer_base[0][1]); | |
657 OUTREG(SCALER_BUF0_OFFSET_V, mach64_buffer_base[0][2]); | |
658 OUTREG(SCALER_BUF1_OFFSET, mach64_buffer_base[0][0]); | |
659 OUTREG(SCALER_BUF1_OFFSET_U, mach64_buffer_base[0][1]); | |
660 OUTREG(SCALER_BUF1_OFFSET_V, mach64_buffer_base[0][2]); | |
661 mach64_wait_vsync(); | |
662 | |
663 mach64_fifo_wait(4); | |
664 OUTREG(OVERLAY_SCALE_CNTL, 0xC4000003); | |
665 // OVERLAY_SCALE_CNTL bits & what they seem to affect | |
666 // bit 0 no effect | |
667 // bit 1 yuv2rgb coeff related | |
668 // bit 2 horizontal interpolation if 0 | |
669 // bit 3 vertical interpolation if 0 | |
670 // bit 4 chroma encoding (0-> 128=neutral / 1-> 0->neutral) | |
671 // bit 5-6 gamma correction | |
672 // bit 7 nothing visible if set | |
673 // bit 8-27 no effect | |
674 // bit 28-31 nothing interresting just crashed my system when i played with them :( | |
675 | |
676 mach64_wait_for_idle(); | |
677 vf = INREG(VIDEO_FORMAT); | |
678 | |
679 // Bits 16-19 seem to select the format | |
680 // 0x0 dunno behaves strange | |
681 // 0x1 dunno behaves strange | |
682 // 0x2 dunno behaves strange | |
683 // 0x3 BGR15 | |
684 // 0x4 BGR16 | |
685 // 0x5 BGR16 (hmm, that need investigation, 2 BGR16 formats, i guess 1 will have only 5bits for green) | |
686 // 0x6 BGR32 | |
687 // 0x7 BGR32 with somehow mixed even / odd pixels ? | |
688 // 0x8 YYYYUVUV | |
689 // 0x9 YVU9 | |
690 // 0xA YV12 | |
691 // 0xB YUY2 | |
692 // 0xC UYVY | |
693 // 0xD UYVY (no difference is visible if i switch between C/D for every even/odd frame) | |
694 // 0xE dunno behaves strange | |
695 // 0xF dunno behaves strange | |
696 // Bit 28 all values are assumed to be 7 bit with chroma=64 for black (tested with YV12 & YUY2) | |
697 // the remaining bits seem to have no effect | |
698 | |
699 | |
700 switch(besr.fourcc) | |
701 { | |
702 /* BGR formats */ | |
703 case IMGFMT_BGR15: OUTREG(VIDEO_FORMAT, 0x00030000); break; | |
704 case IMGFMT_BGR16: OUTREG(VIDEO_FORMAT, 0x00040000); break; | |
705 case IMGFMT_BGR32: OUTREG(VIDEO_FORMAT, 0x00060000); break; | |
706 /* 4:2:0 */ | |
707 case IMGFMT_IYUV: | |
708 case IMGFMT_I420: | |
709 case IMGFMT_YV12: OUTREG(VIDEO_FORMAT, 0x000A0000); break; | |
710 | |
711 case IMGFMT_YVU9: OUTREG(VIDEO_FORMAT, 0x00090000); break; | |
712 /* 4:2:2 */ | |
713 case IMGFMT_YVYU: | |
714 case IMGFMT_UYVY: OUTREG(VIDEO_FORMAT, 0x000C0000); break; | |
715 case IMGFMT_YUY2: | |
716 default: OUTREG(VIDEO_FORMAT, 0x000B0000); break; | |
717 } | |
718 if(__verbose > VERBOSE_LEVEL) mach64_vid_dump_regs(); | |
719 } | |
720 | |
721 static int mach64_vid_init_video( vidix_playback_t *config ) | |
722 { | |
723 uint32_t src_w,src_h,dest_w,dest_h,pitch,h_inc,v_inc,left,leftUV,top,ecp,y_pos; | |
724 int is_420,best_pitch,mpitch; | |
725 int src_offset_y, src_offset_u, src_offset_v; | |
726 unsigned int i; | |
727 | |
728 mach64_vid_stop_video(); | |
729 /* warning, if left or top are != 0 this will fail, as the framesize is too small then */ | |
730 left = config->src.x; | |
731 top = config->src.y; | |
732 src_h = config->src.h; | |
733 src_w = config->src.w; | |
734 is_420 = 0; | |
735 if(config->fourcc == IMGFMT_YV12 || | |
736 config->fourcc == IMGFMT_I420 || | |
737 config->fourcc == IMGFMT_IYUV) is_420 = 1; | |
738 best_pitch = mach64_query_pitch(config->fourcc,&config->src.pitch); | |
739 mpitch = best_pitch-1; | |
740 switch(config->fourcc) | |
741 { | |
742 case IMGFMT_YVU9: | |
743 /* 4:2:0 */ | |
744 case IMGFMT_IYUV: | |
745 case IMGFMT_YV12: | |
746 case IMGFMT_I420: pitch = (src_w + mpitch) & ~mpitch; | |
747 config->dest.pitch.y = | |
748 config->dest.pitch.u = | |
749 config->dest.pitch.v = best_pitch; | |
750 besr.vid_buf_pitch= pitch; | |
751 break; | |
752 /* RGB 4:4:4:4 */ | |
753 case IMGFMT_RGB32: | |
754 case IMGFMT_BGR32: pitch = (src_w*4 + mpitch) & ~mpitch; | |
755 config->dest.pitch.y = | |
756 config->dest.pitch.u = | |
757 config->dest.pitch.v = best_pitch; | |
758 besr.vid_buf_pitch= pitch>>2; | |
759 break; | |
760 /* 4:2:2 */ | |
761 default: /* RGB15, RGB16, YVYU, UYVY, YUY2 */ | |
762 pitch = ((src_w*2) + mpitch) & ~mpitch; | |
763 config->dest.pitch.y = | |
764 config->dest.pitch.u = | |
765 config->dest.pitch.v = best_pitch; | |
766 besr.vid_buf_pitch= pitch>>1; | |
767 break; | |
768 } | |
769 dest_w = config->dest.w; | |
770 dest_h = config->dest.h; | |
771 besr.fourcc = config->fourcc; | |
772 ecp = (INPLL(PLL_VCLK_CNTL) & PLL_ECP_DIV) >> 4; | |
23048 | 773 |
22850 | 774 if(__verbose>0) printf("[mach64] ecp: %d\n", ecp); |
775 v_inc = src_h * mach64_get_vert_stretch(); | |
776 | |
777 if(mach64_is_interlace()) v_inc<<=1; | |
778 if(mach64_is_dbl_scan() ) v_inc>>=1; | |
779 v_inc>>=4; // convert 16.16 -> 20.12 | |
780 v_inc/= dest_h; | |
781 | |
782 h_inc = (src_w << (12+ecp)) / dest_w; | |
783 /* keep everything in 16.16 */ | |
784 config->offsets[0] = 0; | |
785 for(i=1; i<config->num_frames; i++) | |
786 config->offsets[i] = config->offsets[i-1] + config->frame_size; | |
787 | |
788 /*FIXME the left / top stuff is broken (= zoom a src rectangle from a larger one) | |
789 1. the framesize isn't known as the outer src rectangle dimensions aren't known | |
790 2. the mach64 needs aligned addresses so it can't work anyway | |
791 -> so we could shift the outer buffer to compensate that but that would mean | |
792 alignment problems for the code which writes into it | |
793 */ | |
794 | |
795 if(is_420) | |
796 { | |
797 config->offset.y= 0; | |
798 config->offset.u= (pitch*src_h + 15)&~15; | |
799 config->offset.v= (config->offset.u + (pitch*src_h>>2) + 15)&~15; | |
800 | |
801 if(besr.fourcc == IMGFMT_I420 || besr.fourcc == IMGFMT_IYUV) | |
802 { | |
803 uint32_t tmp; | |
804 tmp = config->offset.u; | |
805 config->offset.u = config->offset.v; | |
806 config->offset.v = tmp; | |
807 } | |
808 | |
809 src_offset_y= config->offset.y + top*pitch + left; | |
810 src_offset_u= config->offset.u + (top*pitch>>2) + (left>>1); | |
811 src_offset_v= config->offset.v + (top*pitch>>2) + (left>>1); | |
812 } | |
813 else if(besr.fourcc == IMGFMT_YVU9) | |
814 { | |
815 config->offset.y= 0; | |
816 config->offset.u= (pitch*src_h + 15)&~15; | |
817 config->offset.v= (config->offset.u + (pitch*src_h>>4) + 15)&~15; | |
818 | |
819 src_offset_y= config->offset.y + top*pitch + left; | |
820 src_offset_u= config->offset.u + (top*pitch>>4) + (left>>1); | |
821 src_offset_v= config->offset.v + (top*pitch>>4) + (left>>1); | |
822 } | |
823 else if(besr.fourcc == IMGFMT_BGR32) | |
824 { | |
825 config->offset.y = config->offset.u = config->offset.v = 0; | |
826 src_offset_y= src_offset_u= src_offset_v= top*pitch + (left << 2); | |
827 } | |
828 else | |
829 { | |
830 config->offset.y = config->offset.u = config->offset.v = 0; | |
831 src_offset_y= src_offset_u= src_offset_v= top*pitch + (left << 1); | |
832 } | |
833 | |
834 num_mach64_buffers= config->num_frames; | |
835 for(i=0; i<config->num_frames; i++) | |
836 { | |
837 mach64_buffer_base[i][0]= (mach64_overlay_offset + config->offsets[i] + src_offset_y)&~15; | |
838 mach64_buffer_base[i][1]= (mach64_overlay_offset + config->offsets[i] + src_offset_u)&~15; | |
839 mach64_buffer_base[i][2]= (mach64_overlay_offset + config->offsets[i] + src_offset_v)&~15; | |
840 } | |
841 | |
842 leftUV = (left >> 17) & 15; | |
843 left = (left >> 16) & 15; | |
844 besr.scale_inc = ( h_inc << 16 ) | v_inc; | |
845 y_pos = config->dest.y; | |
846 if(mach64_is_dbl_scan()) y_pos*=2; | |
847 else | |
848 if(mach64_is_interlace()) y_pos/=2; | |
849 besr.y_x_start = y_pos | (config->dest.x << 16); | |
850 y_pos =config->dest.y + dest_h; | |
851 if(mach64_is_dbl_scan()) y_pos*=2; | |
852 else | |
853 if(mach64_is_interlace()) y_pos/=2; | |
854 besr.y_x_end = y_pos | ((config->dest.x + dest_w) << 16); | |
855 besr.height_width = ((src_w - left)<<16) | (src_h - top); | |
856 | |
857 return 0; | |
858 } | |
859 | |
860 static int is_supported_fourcc(uint32_t fourcc) | |
861 { | |
862 switch(fourcc) | |
863 { | |
864 case IMGFMT_YV12: | |
865 case IMGFMT_I420: | |
866 case IMGFMT_YVU9: | |
867 case IMGFMT_IYUV: | |
868 return supports_planar; | |
869 case IMGFMT_YUY2: | |
870 case IMGFMT_UYVY: | |
871 case IMGFMT_BGR15: | |
872 case IMGFMT_BGR16: | |
873 case IMGFMT_BGR32: | |
874 return 1; | |
875 default: | |
876 return 0; | |
877 } | |
878 } | |
879 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
880 static int mach64_query_fourcc(vidix_fourcc_t *to) |
22850 | 881 { |
882 if(is_supported_fourcc(to->fourcc)) | |
883 { | |
23060 | 884 to->depth = VID_DEPTH_ALL; |
22850 | 885 to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; |
886 return 0; | |
887 } | |
888 else to->depth = to->flags = 0; | |
889 return ENOSYS; | |
890 } | |
891 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
892 static int mach64_config_playback(vidix_playback_t *info) |
22850 | 893 { |
894 if(!is_supported_fourcc(info->fourcc)) return ENOSYS; | |
895 | |
896 mach64_compute_framesize(info); | |
897 | |
898 if(info->num_frames>4) info->num_frames=4; | |
899 for(;info->num_frames>0; info->num_frames--) | |
900 { | |
901 mach64_overlay_offset = mach64_ram_size - info->frame_size*info->num_frames; | |
902 mach64_overlay_offset &= 0xffff0000; | |
903 if(mach64_overlay_offset>0) break; | |
904 } | |
905 if(info->num_frames <= 0) return EINVAL; | |
906 | |
907 info->dga_addr = (char *)mach64_mem_base + mach64_overlay_offset; | |
908 mach64_vid_init_video(info); | |
909 return 0; | |
910 } | |
911 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
912 static int mach64_playback_on(void) |
22850 | 913 { |
914 mach64_vid_display_video(); | |
915 return 0; | |
916 } | |
917 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
918 static int mach64_playback_off(void) |
22850 | 919 { |
920 mach64_vid_stop_video(); | |
921 return 0; | |
922 } | |
923 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
924 static int mach64_frame_sel(unsigned int frame) |
22850 | 925 { |
926 uint32_t off[6]; | |
927 int i; | |
928 int last_frame= (frame-1+num_mach64_buffers) % num_mach64_buffers; | |
929 //printf("Selecting frame %d\n", frame); | |
930 /* | |
931 buf3-5 always should point onto second buffer for better | |
932 deinterlacing and TV-in | |
933 */ | |
934 if(num_mach64_buffers==1) return 0; | |
935 | |
936 for(i=0; i<3; i++) | |
937 { | |
938 off[i] = mach64_buffer_base[frame][i]; | |
939 off[i+3]= mach64_buffer_base[last_frame][i]; | |
940 } | |
941 | |
942 mach64_wait_for_idle(); | |
943 mach64_fifo_wait(7); | |
944 | |
945 OUTREG(SCALER_BUF0_OFFSET, off[0]); | |
946 OUTREG(SCALER_BUF0_OFFSET_U, off[1]); | |
947 OUTREG(SCALER_BUF0_OFFSET_V, off[2]); | |
948 OUTREG(SCALER_BUF1_OFFSET, off[3]); | |
949 OUTREG(SCALER_BUF1_OFFSET_U, off[4]); | |
950 OUTREG(SCALER_BUF1_OFFSET_V, off[5]); | |
951 if(num_mach64_buffers==2) mach64_wait_vsync(); //only wait for vsync if we do double buffering | |
952 | |
953 if(__verbose > VERBOSE_LEVEL) mach64_vid_dump_regs(); | |
954 return 0; | |
955 } | |
956 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
957 static vidix_video_eq_t equal = |
22850 | 958 { |
959 VEQ_CAP_BRIGHTNESS | VEQ_CAP_SATURATION | |
960 , | |
961 0, 0, 0, 0, 0, 0, 0, 0 }; | |
962 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
963 static int mach64_get_eq( vidix_video_eq_t * eq) |
22850 | 964 { |
965 memcpy(eq,&equal,sizeof(vidix_video_eq_t)); | |
966 return 0; | |
967 } | |
968 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
969 static int mach64_set_eq( const vidix_video_eq_t * eq) |
22850 | 970 { |
971 int br,sat; | |
972 if(eq->cap & VEQ_CAP_BRIGHTNESS) equal.brightness = eq->brightness; | |
973 if(eq->cap & VEQ_CAP_CONTRAST) equal.contrast = eq->contrast; | |
974 if(eq->cap & VEQ_CAP_SATURATION) equal.saturation = eq->saturation; | |
975 if(eq->cap & VEQ_CAP_HUE) equal.hue = eq->hue; | |
976 if(eq->cap & VEQ_CAP_RGB_INTENSITY) | |
977 { | |
978 equal.red_intensity = eq->red_intensity; | |
979 equal.green_intensity = eq->green_intensity; | |
980 equal.blue_intensity = eq->blue_intensity; | |
981 } | |
982 equal.flags = eq->flags; | |
983 br = equal.brightness * 64 / 1000; | |
984 if(br < -64) br = -64; if(br > 63) br = 63; | |
985 sat = (equal.saturation + 1000) * 16 / 1000; | |
986 if(sat < 0) sat = 0; if(sat > 31) sat = 31; | |
987 OUTREG(SCALER_COLOUR_CNTL, (br & 0x7f) | (sat << 8) | (sat << 16)); | |
988 return 0; | |
989 } | |
990 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
991 static int mach64_get_gkeys(vidix_grkey_t *grkey) |
22850 | 992 { |
993 memcpy(grkey, &mach64_grkey, sizeof(vidix_grkey_t)); | |
994 return(0); | |
995 } | |
996 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
997 static int mach64_set_gkeys(const vidix_grkey_t *grkey) |
22850 | 998 { |
999 memcpy(&mach64_grkey, grkey, sizeof(vidix_grkey_t)); | |
1000 | |
1001 if(mach64_grkey.ckey.op == CKEY_TRUE) | |
1002 { | |
1003 besr.ckey_on=1; | |
1004 | |
1005 switch(mach64_vid_get_dbpp()) | |
1006 { | |
1007 case 15: | |
1008 besr.graphics_key_msk=0x7FFF; | |
1009 besr.graphics_key_clr= | |
1010 ((mach64_grkey.ckey.blue &0xF8)>>3) | |
1011 | ((mach64_grkey.ckey.green&0xF8)<<2) | |
1012 | ((mach64_grkey.ckey.red &0xF8)<<7); | |
1013 break; | |
1014 case 16: | |
1015 besr.graphics_key_msk=0xFFFF; | |
1016 besr.graphics_key_clr= | |
1017 ((mach64_grkey.ckey.blue &0xF8)>>3) | |
1018 | ((mach64_grkey.ckey.green&0xFC)<<3) | |
1019 | ((mach64_grkey.ckey.red &0xF8)<<8); | |
1020 //besr.graphics_key_clr=le2me_32(besr.graphics_key_clr); | |
1021 break; | |
1022 case 24: | |
1023 besr.graphics_key_msk=0xFFFFFF; | |
1024 besr.graphics_key_clr= | |
1025 ((mach64_grkey.ckey.blue &0xFF)) | |
1026 | ((mach64_grkey.ckey.green&0xFF)<<8) | |
1027 | ((mach64_grkey.ckey.red &0xFF)<<16); | |
1028 break; | |
1029 case 32: | |
1030 besr.graphics_key_msk=0xFFFFFF; | |
1031 besr.graphics_key_clr= | |
1032 ((mach64_grkey.ckey.blue &0xFF)) | |
1033 | ((mach64_grkey.ckey.green&0xFF)<<8) | |
1034 | ((mach64_grkey.ckey.red &0xFF)<<16); | |
1035 break; | |
1036 default: | |
1037 besr.ckey_on=0; | |
1038 besr.graphics_key_msk=0; | |
1039 besr.graphics_key_clr=0; | |
1040 } | |
1041 } | |
1042 else | |
1043 { | |
1044 besr.ckey_on=0; | |
1045 besr.graphics_key_msk=0; | |
1046 besr.graphics_key_clr=0; | |
1047 } | |
1048 | |
1049 mach64_fifo_wait(4); | |
1050 OUTREG(OVERLAY_GRAPHICS_KEY_MSK, besr.graphics_key_msk); | |
1051 OUTREG(OVERLAY_GRAPHICS_KEY_CLR, besr.graphics_key_clr); | |
1052 // OUTREG(OVERLAY_VIDEO_KEY_MSK, 0); | |
1053 // OUTREG(OVERLAY_VIDEO_KEY_CLR, 0); | |
1054 if(besr.ckey_on) | |
1055 OUTREG(OVERLAY_KEY_CNTL,VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_EQ|CMP_MIX_AND); | |
1056 else | |
1057 OUTREG(OVERLAY_KEY_CNTL,VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_TRUE|CMP_MIX_AND); | |
1058 | |
1059 return(0); | |
1060 } | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1061 |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1062 VDXDriver mach64_drv = { |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1063 "mach64", |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1064 NULL, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1065 .probe = mach64_probe, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1066 .get_caps = mach64_get_caps, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1067 .query_fourcc = mach64_query_fourcc, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1068 .init = mach64_init, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1069 .destroy = mach64_destroy, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1070 .config_playback = mach64_config_playback, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1071 .playback_on = mach64_playback_on, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1072 .playback_off = mach64_playback_off, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1073 .frame_sel = mach64_frame_sel, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1074 .get_eq = mach64_get_eq, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1075 .set_eq = mach64_set_eq, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1076 .get_gkey = mach64_get_gkeys, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1077 .set_gkey = mach64_set_gkeys, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1078 }; |