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