Mercurial > mplayer.hg
annotate vidix/drivers/nvidia_vid.c @ 15533:ddf15d233d58
Do not switch to audio tracks whose codec private data differs from the main audio track's as this will most likely result in messed up audio output. Patch by Michael Behrisch <list () behrisch ! de>
author | mosu |
---|---|
date | Sat, 21 May 2005 06:50:08 +0000 |
parents | 6a49dea2c0e2 |
children | 8e859a01904f |
rev | line source |
---|---|
10954 | 1 /* |
2 nvidia_vid - VIDIX based video driver for NVIDIA chips | |
11902 | 3 Copyrights 2003 - 2004 Sascha Sommer. This file is based on sources from |
10954 | 4 RIVATV (rivatv.sf.net) |
5 Licence: GPL | |
11159 | 6 WARNING: THIS DRIVER IS IN BETA STAGE |
10954 | 7 |
11086 | 8 multi buffer support and TNT2 fixes by Dmitry Baryshkov |
10954 | 9 */ |
10 | |
11 | |
12 #include <errno.h> | |
13 #include <stdio.h> | |
14 #include <stdlib.h> | |
15 #include <string.h> | |
16 #include <inttypes.h> | |
17 #include <unistd.h> | |
18 | |
19 | |
20 #include "../vidix.h" | |
21 #include "../fourcc.h" | |
22 #include "../../libdha/libdha.h" | |
23 #include "../../libdha/pci_ids.h" | |
24 #include "../../libdha/pci_names.h" | |
25 #include "../../config.h" | |
26 #include "../../bswap.h" | |
27 | |
28 | |
29 pciinfo_t pci_info; | |
30 | |
31 | |
32 #define MAX_FRAMES 3 | |
33 #define NV04_BES_SIZE 1024*2000*4 | |
34 | |
35 | |
36 static vidix_capability_t nvidia_cap = { | |
37 "NVIDIA RIVA OVERLAY DRIVER", | |
38 "Sascha Sommer <saschasommer@freenet.de>", | |
39 TYPE_OUTPUT, | |
40 { 0, 0, 0, 0 }, | |
10957
4d4d0c1c7142
according to xfree cvs maximum overlay size is only 2046x2046
atmos4
parents:
10954
diff
changeset
|
41 2046, |
4d4d0c1c7142
according to xfree cvs maximum overlay size is only 2046x2046
atmos4
parents:
10954
diff
changeset
|
42 2046, |
10954 | 43 4, |
44 4, | |
45 -1, | |
46 FLAG_UPSCALER|FLAG_DOWNSCALER, | |
47 VENDOR_NVIDIA2, | |
48 -1, | |
49 { 0, 0, 0, 0 } | |
50 }; | |
51 | |
52 | |
53 unsigned int vixGetVersion(void){ | |
54 return(VIDIX_VERSION); | |
55 } | |
56 | |
57 | |
58 #define NV_ARCH_03 0x03 | |
59 #define NV_ARCH_04 0x04 | |
60 #define NV_ARCH_10 0x10 | |
61 #define NV_ARCH_20 0x20 | |
62 #define NV_ARCH_30 0x30 | |
63 | |
64 struct nvidia_cards { | |
65 unsigned short chip_id; | |
66 unsigned short arch; | |
67 }; | |
68 | |
69 | |
70 static struct nvidia_cards nvidia_card_ids[] = { | |
11073 | 71 /*NV03*/ |
10954 | 72 {DEVICE_NVIDIA2_RIVA128, NV_ARCH_03}, |
11073 | 73 {DEVICE_NVIDIA2_RIVA128ZX,NV_ARCH_03}, |
74 /*NV04*/ | |
75 {DEVICE_NVIDIA_NV4_RIVA_TNT,NV_ARCH_04}, | |
76 {DEVICE_NVIDIA_NV5_RIVA_TNT2,NV_ARCH_04}, | |
77 {DEVICE_NVIDIA_NV5_RIVA_TNT22,NV_ARCH_04}, | |
78 {DEVICE_NVIDIA_NV5_RIVA_TNT23,NV_ARCH_04}, | |
79 {DEVICE_NVIDIA_NV5_RIVA_TNT24,NV_ARCH_04}, | |
80 {DEVICE_NVIDIA_NV6_VANTA,NV_ARCH_04}, | |
10954 | 81 {DEVICE_NVIDIA_RIVA_TNT2_MODEL,NV_ARCH_04}, |
11073 | 82 {DEVICE_NVIDIA_NV6_VANTA2,NV_ARCH_04}, |
83 {DEVICE_NVIDIA_NV6_VANTA3,NV_ARCH_04}, | |
84 {DEVICE_NVIDIA_NV5_RIVA_TNT25,NV_ARCH_04}, | |
10954 | 85 {DEVICE_NVIDIA2_TNT,NV_ARCH_04}, |
11073 | 86 {DEVICE_NVIDIA2_TNT2,NV_ARCH_04}, |
87 {DEVICE_NVIDIA2_VTNT2,NV_ARCH_04}, | |
10954 | 88 {DEVICE_NVIDIA2_UTNT2 ,NV_ARCH_04}, |
89 {DEVICE_NVIDIA2_ITNT2,NV_ARCH_04}, | |
11073 | 90 /*NV10*/ |
91 {DEVICE_NVIDIA_NV10_GEFORCE_256,NV_ARCH_10}, | |
92 {DEVICE_NVIDIA_NV10_GEFORCE_2562,NV_ARCH_10}, | |
93 {DEVICE_NVIDIA_NV11_GEFORCE2_MX,NV_ARCH_10}, | |
94 {DEVICE_NVIDIA_NV11_GEFORCE2_MX2,NV_ARCH_10}, | |
95 {DEVICE_NVIDIA_NV11_GEFORCE2_GO,NV_ARCH_10}, | |
96 {DEVICE_NVIDIA_NV11_GEFORCE2_MXR ,NV_ARCH_10}, | |
97 {DEVICE_NVIDIA_NV15_GEFORCE2_GTS,NV_ARCH_10}, | |
98 {DEVICE_NVIDIA_NV15_GEFORCE2_TI,NV_ARCH_10}, | |
99 {DEVICE_NVIDIA_NV15_GEFORCE2_ULTRA,NV_ARCH_10}, | |
100 {DEVICE_NVIDIA_NV17_GEFORCE4_MX460,NV_ARCH_10}, | |
101 {DEVICE_NVIDIA_NV17_GEFORCE4_MX440,NV_ARCH_10}, | |
102 {DEVICE_NVIDIA_NV17_GEFORCE4_MX420,NV_ARCH_10}, | |
103 {DEVICE_NVIDIA_NV17_GEFORCE4_440,NV_ARCH_10}, | |
104 {DEVICE_NVIDIA_NV17_GEFORCE4_420,NV_ARCH_10}, | |
105 {DEVICE_NVIDIA_NV17_GEFORCE4_4202,NV_ARCH_10}, | |
106 {DEVICE_NVIDIA_NV17_GEFORCE4_4402,NV_ARCH_10}, | |
107 {DEVICE_NVIDIA_NV18_GEFORCE4_MX440,NV_ARCH_10}, | |
108 {DEVICE_NVIDIA_NV15_GEFORCE2,NV_ARCH_10}, | |
109 /*NV20*/ | |
110 {DEVICE_NVIDIA_NV20_GEFORCE3,NV_ARCH_20}, | |
111 {DEVICE_NVIDIA_NV20_GEFORCE3_TI200,NV_ARCH_20}, | |
112 {DEVICE_NVIDIA_NV20_GEFORCE3_TI500,NV_ARCH_20}, | |
113 {DEVICE_NVIDIA_NV25_GEFORCE4_TI4600,NV_ARCH_20}, | |
114 {DEVICE_NVIDIA_NV25_GEFORCE4_TI4400,NV_ARCH_20}, | |
115 {DEVICE_NVIDIA_NV25_GEFORCE4_TI4200,NV_ARCH_20}, | |
11895
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
116 {DEVICE_NVIDIA_QUADRO4_900XGL,NV_ARCH_20}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
117 {DEVICE_NVIDIA_QUADRO4_750XGL,NV_ARCH_20}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
118 {DEVICE_NVIDIA_QUADRO4_700XGL,NV_ARCH_20}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
119 {DEVICE_NVIDIA_NV28_GEFORCE4_TI,NV_ARCH_20}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
120 {DEVICE_NVIDIA_NV28_GEFORCE4_TI2,NV_ARCH_20}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
121 {DEVICE_NVIDIA_NV28_GEFORCE4_TI3,NV_ARCH_20}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
122 {DEVICE_NVIDIA_NV28_GEFORCE4_TI4,NV_ARCH_20}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
123 {DEVICE_NVIDIA_NV28GL_QUADRO4_980,NV_ARCH_20}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
124 {DEVICE_NVIDIA_NV28GL_QUADRO4_780,NV_ARCH_20}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
125 /*NV30*/ |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
126 {DEVICE_NVIDIA_NV30_GEFORCE_FX,NV_ARCH_30}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
127 {DEVICE_NVIDIA_NV30_GEFORCE_FX2,NV_ARCH_30}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
128 {DEVICE_NVIDIA_NV30_GEFORCE_FX3,NV_ARCH_30}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
129 {DEVICE_NVIDIA_NV30GL_QUADRO_FX,NV_ARCH_30}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
130 {DEVICE_NVIDIA_NV30GL_QUADRO_FX2,NV_ARCH_30}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
131 {DEVICE_NVIDIA_NV31_GEFORCE_FX,NV_ARCH_30}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
132 {DEVICE_NVIDIA_NV31_GEFORCE_FX2,NV_ARCH_30}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
133 {DEVICE_NVIDIA_NV34_GEFORCE_FX,NV_ARCH_30}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
134 {DEVICE_NVIDIA_NV34_GEFORCE_FX2,NV_ARCH_30}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
135 {DEVICE_NVIDIA_NV34GL_QUADRO_FX,NV_ARCH_30}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
136 {DEVICE_NVIDIA_NV35_GEFORCE_FX,NV_ARCH_30}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
137 {DEVICE_NVIDIA_NV35_GEFORCE_FX2,NV_ARCH_30}, |
d9489d5581d0
a few more nvidia cards (only tested card is GeForceFX 5200)
faust3
parents:
11783
diff
changeset
|
138 {DEVICE_NVIDIA_NV35GL_QUADRO_FX,NV_ARCH_30} |
10954 | 139 }; |
140 | |
141 | |
142 static int find_chip(unsigned chip_id){ | |
143 unsigned i; | |
144 for(i = 0;i < sizeof(nvidia_card_ids)/sizeof(struct nvidia_cards);i++) | |
145 { | |
146 if(chip_id == nvidia_card_ids[i].chip_id)return i; | |
147 } | |
148 return -1; | |
149 } | |
150 | |
151 int vixProbe(int verbose, int force){ | |
152 pciinfo_t lst[MAX_PCI_DEVICES]; | |
153 unsigned i,num_pci; | |
154 int err; | |
155 | |
156 if (force) | |
157 printf("[nvidia_vid]: warning: forcing not supported yet!\n"); | |
158 err = pci_scan(lst,&num_pci); | |
159 if(err){ | |
11678
972d1998bde9
occured --> occurred typo patch by Clinton Roy <croy@dstc.edu.au>
diego
parents:
11233
diff
changeset
|
160 printf("[nvidia_vid] Error occurred during pci scan: %s\n",strerror(err)); |
10954 | 161 return err; |
162 } | |
163 else { | |
164 err = ENXIO; | |
165 for(i=0; i < num_pci; i++){ | |
166 if(lst[i].vendor == VENDOR_NVIDIA2 || lst[i].vendor == VENDOR_NVIDIA){ | |
167 int idx; | |
168 const char *dname; | |
169 idx = find_chip(lst[i].device); | |
170 if(idx == -1) | |
171 continue; | |
172 dname = pci_device_name(lst[i].vendor, lst[i].device); | |
173 dname = dname ? dname : "Unknown chip"; | |
174 printf("[nvidia_vid] Found chip: %s\n", dname); | |
175 if ((lst[i].command & PCI_COMMAND_IO) == 0){ | |
176 printf("[nvidia_vid] Device is disabled, ignoring\n"); | |
177 continue; | |
178 } | |
179 nvidia_cap.device_id = lst[i].device; | |
180 err = 0; | |
181 memcpy(&pci_info, &lst[i], sizeof(pciinfo_t)); | |
182 break; | |
183 } | |
184 } | |
185 } | |
186 if(err && verbose) printf("[nvidia_vid] Can't find chip\n"); | |
187 return err; | |
188 } | |
189 | |
190 | |
191 | |
192 | |
193 /* | |
194 * PCI-Memory IO access macros. | |
195 */ | |
196 #define VID_WR08(p,i,val) (((uint8_t *)(p))[(i)]=(val)) | |
197 #define VID_RD08(p,i) (((uint8_t *)(p))[(i)]) | |
198 | |
199 #define VID_WR32(p,i,val) (((uint32_t *)(p))[(i)/4]=(val)) | |
200 #define VID_RD32(p,i) (((uint32_t *)(p))[(i)/4]) | |
201 | |
202 #ifndef USE_RMW_CYCLES | |
203 /* | |
204 * Can be used to inhibit READ-MODIFY-WRITE cycles. On by default. | |
205 */ | |
206 | |
207 #define MEM_BARRIER() __asm__ __volatile__ ("" : : : "memory") | |
208 | |
209 #undef VID_WR08 | |
210 #define VID_WR08(p,i,val) ({ MEM_BARRIER(); ((uint8_t *)(p))[(i)]=(val); }) | |
211 #undef VID_RD08 | |
212 #define VID_RD08(p,i) ({ MEM_BARRIER(); ((uint8_t *)(p))[(i)]; }) | |
213 | |
214 #undef VID_WR32 | |
215 #define VID_WR32(p,i,val) ({ MEM_BARRIER(); ((uint32_t *)(p))[(i)/4]=(val); }) | |
216 #undef VID_RD32 | |
217 #define VID_RD32(p,i) ({ MEM_BARRIER(); ((uint32_t *)(p))[(i)/4]; }) | |
218 #endif /* USE_RMW_CYCLES */ | |
219 | |
220 #define VID_AND32(p,i,val) VID_WR32(p,i,VID_RD32(p,i)&(val)) | |
221 #define VID_OR32(p,i,val) VID_WR32(p,i,VID_RD32(p,i)|(val)) | |
222 #define VID_XOR32(p,i,val) VID_WR32(p,i,VID_RD32(p,i)^(val)) | |
223 | |
224 | |
225 | |
226 | |
227 | |
228 | |
229 struct rivatv_chip { | |
230 volatile uint32_t *PMC; /* general control */ | |
231 volatile uint32_t *PME; /* multimedia port */ | |
232 volatile uint32_t *PFB; /* framebuffer control */ | |
233 volatile uint32_t *PVIDEO; /* overlay control */ | |
234 volatile uint8_t *PCIO; /* SVGA (CRTC, ATTR) registers */ | |
235 volatile uint8_t *PVIO; /* SVGA (MISC, GRAPH, SEQ) registers */ | |
236 volatile uint32_t *PRAMIN; /* instance memory */ | |
237 volatile uint32_t *PRAMHT; /* hash table */ | |
238 volatile uint32_t *PRAMFC; /* fifo context table */ | |
239 volatile uint32_t *PRAMRO; /* fifo runout table */ | |
240 volatile uint32_t *PFIFO; /* fifo control region */ | |
241 volatile uint32_t *FIFO; /* fifo channels (USER) */ | |
242 volatile uint32_t *PGRAPH; /* graphics engine */ | |
243 | |
244 unsigned long fbsize; /* framebuffer size */ | |
245 int arch; /* compatible NV_ARCH_XX define */ | |
246 int realarch; /* real architecture */ | |
247 void (* lock) (struct rivatv_chip *, int); | |
248 }; | |
249 typedef struct rivatv_chip rivatv_chip; | |
250 | |
251 | |
11086 | 252 struct rivatv_info { |
253 unsigned int use_colorkey; | |
10954 | 254 unsigned int colorkey; /* saved xv colorkey*/ |
255 unsigned int vidixcolorkey; /*currently used colorkey*/ | |
256 unsigned int depth; | |
257 unsigned int format; | |
258 unsigned int pitch; | |
259 unsigned int width,height; | |
260 unsigned int d_width,d_height; /*scaled width && height*/ | |
261 unsigned int wx,wy; /*window x && y*/ | |
262 unsigned int screen_x; /*screen width*/ | |
11085 | 263 unsigned int screen_y; /*screen height*/ |
10954 | 264 unsigned long buffer_size; /* size of the image buffer */ |
265 struct rivatv_chip chip; /* NV architecture structure */ | |
266 void* video_base; /* virtual address of control region */ | |
267 void* control_base; /* virtual address of fb region */ | |
268 unsigned long picture_base; /* direct pointer to video picture */ | |
269 unsigned long picture_offset; /* offset of video picture in frame buffer */ | |
270 // struct rivatv_dma dma; /* DMA structure */ | |
11783 | 271 unsigned int cur_frame; |
10954 | 272 unsigned int num_frames; /* number of buffers */ |
11783 | 273 int bps; /* bytes per line */ |
10954 | 274 }; |
275 typedef struct rivatv_info rivatv_info; | |
276 | |
277 //framebuffer size funcs | |
278 static unsigned long rivatv_fbsize_nv03 (struct rivatv_chip *chip){ | |
279 if (VID_RD32 (chip->PFB, 0) & 0x00000020) { | |
280 if (((VID_RD32 (chip->PMC, 0) & 0xF0) == 0x20) | |
281 && ((VID_RD32 (chip->PMC, 0) & 0x0F) >= 0x02)) { | |
282 /* SDRAM 128 ZX. */ | |
283 return ((1 << (VID_RD32 (chip->PFB, 0) & 0x03)) * 1024 * 1024); | |
284 } | |
285 else { | |
286 return 1024 * 1024 * 8; | |
287 } | |
288 } | |
289 else { | |
290 /* SGRAM 128. */ | |
291 switch (chip->PFB[0x00000000] & 0x00000003) { | |
292 case 0: | |
293 return 1024 * 1024 * 8; | |
294 break; | |
295 case 2: | |
296 return 1024 * 1024 * 4; | |
297 break; | |
298 default: | |
299 return 1024 * 1024 * 2; | |
300 break; | |
301 } | |
302 } | |
303 } | |
304 static unsigned long rivatv_fbsize_nv04 (struct rivatv_chip *chip){ | |
305 if (VID_RD32 (chip->PFB, 0) & 0x00000100) { | |
306 return ((VID_RD32 (chip->PFB, 0) >> 12) & 0x0F) * 1024 * 1024 * 2 | |
307 + 1024 * 1024 * 2; | |
308 } else { | |
309 switch (VID_RD32 (chip->PFB, 0) & 0x00000003) { | |
310 case 0: | |
311 return 1024 * 1024 * 32; | |
312 break; | |
313 case 1: | |
314 return 1024 * 1024 * 4; | |
315 break; | |
316 case 2: | |
317 return 1024 * 1024 * 8; | |
318 break; | |
319 case 3: | |
320 default: | |
321 return 1024 * 1024 * 16; | |
322 break; | |
323 } | |
324 } | |
325 } | |
326 | |
327 static unsigned long rivatv_fbsize_nv10 (struct rivatv_chip *chip){ | |
328 return ((VID_RD32 (chip->PFB, 0x20C) >> 20) & 0x000000FF) * 1024 * 1024; | |
329 } | |
330 | |
331 //lock funcs | |
332 static void rivatv_lock_nv03 (struct rivatv_chip *chip, int LockUnlock){ | |
333 VID_WR08 (chip->PVIO, 0x3C4, 0x06); | |
334 VID_WR08 (chip->PVIO, 0x3C5, LockUnlock ? 0x99 : 0x57); | |
335 } | |
336 | |
337 static void rivatv_lock_nv04 (struct rivatv_chip *chip, int LockUnlock){ | |
338 VID_WR08 (chip->PCIO, 0x3C4, 0x06); | |
339 VID_WR08 (chip->PCIO, 0x3C5, LockUnlock ? 0x99 : 0x57); | |
340 VID_WR08 (chip->PCIO, 0x3D4, 0x1F); | |
341 VID_WR08 (chip->PCIO, 0x3D5, LockUnlock ? 0x99 : 0x57); | |
342 } | |
343 | |
344 | |
345 | |
346 | |
347 /* Enable PFB (Framebuffer), PVIDEO (Overlay unit) and PME (Mediaport) if neccessary. */ | |
348 static void rivatv_enable_PMEDIA (struct rivatv_info *info){ | |
349 uint32_t reg; | |
350 | |
351 /* switch off interrupts once for a while */ | |
352 // VID_WR32 (info->chip.PME, 0x200140, 0x00); | |
353 // VID_WR32 (info->chip.PMC, 0x000140, 0x00); | |
354 | |
355 reg = VID_RD32 (info->chip.PMC, 0x000200); | |
356 | |
357 /* NV3 (0x10100010): NV03_PMC_ENABLE_PMEDIA, NV03_PMC_ENABLE_PFB, NV03_PMC_ENABLE_PVIDEO */ | |
358 | |
359 if ((reg & 0x10100010) != 0x10100010) { | |
360 printf("PVIDEO and PFB disabled, enabling...\n"); | |
361 VID_OR32 (info->chip.PMC, 0x000200, 0x10100010); | |
362 } | |
363 | |
364 /* save the current colorkey */ | |
365 switch (info->chip.arch ) { | |
366 case NV_ARCH_10: | |
367 case NV_ARCH_20: | |
368 case NV_ARCH_30: | |
369 /* NV_PVIDEO_COLOR_KEY */ | |
370 info->colorkey = VID_RD32 (info->chip.PVIDEO, 0xB00); | |
371 break; | |
372 case NV_ARCH_03: | |
373 case NV_ARCH_04: | |
374 /* NV_PVIDEO_KEY */ | |
375 info->colorkey = VID_RD32 (info->chip.PVIDEO, 0x240); | |
376 break; | |
377 } | |
378 | |
379 | |
380 /* re-enable interrupts again */ | |
381 // VID_WR32 (info->chip.PMC, 0x000140, 0x01); | |
382 // VID_WR32 (info->chip.PME, 0x200140, 0x01); | |
383 } | |
384 | |
385 /* Stop overlay video. */ | |
386 void rivatv_overlay_stop (struct rivatv_info *info) { | |
387 switch (info->chip.arch ) { | |
388 case NV_ARCH_10: | |
389 case NV_ARCH_20: | |
390 case NV_ARCH_30: | |
391 /* NV_PVIDEO_COLOR_KEY */ | |
392 /* Xv-Extension-Hack: Restore previously saved value. */ | |
393 VID_WR32 (info->chip.PVIDEO, 0xB00, info->colorkey); | |
394 /* NV_PVIDEO_STOP */ | |
395 VID_OR32 (info->chip.PVIDEO, 0x704, 0x11); | |
396 /* NV_PVIDEO_BUFFER */ | |
397 VID_AND32 (info->chip.PVIDEO, 0x700, ~0x11); | |
398 /* NV_PVIDEO_INTR_EN_BUFFER */ | |
11086 | 399 // VID_AND32 (info->chip.PVIDEO, 0x140, ~0x11); |
10954 | 400 break; |
401 case NV_ARCH_03: | |
402 case NV_ARCH_04: | |
403 /* NV_PVIDEO_KEY */ | |
404 VID_WR32 (info->chip.PVIDEO, 0x240, info->colorkey); | |
405 /* NV_PVIDEO_OVERLAY_VIDEO_OFF */ | |
406 VID_AND32 (info->chip.PVIDEO, 0x244, ~0x01); | |
407 /* NV_PVIDEO_INTR_EN_0_NOTIFY */ | |
11086 | 408 // VID_AND32 (info->chip.PVIDEO, 0x140, ~0x01); |
10954 | 409 /* NV_PVIDEO_OE_STATE */ |
410 VID_WR32 (info->chip.PVIDEO, 0x224, 0); | |
411 /* NV_PVIDEO_SU_STATE */ | |
412 VID_WR32 (info->chip.PVIDEO, 0x228, 0); | |
413 /* NV_PVIDEO_RM_STATE */ | |
414 VID_WR32 (info->chip.PVIDEO, 0x22C, 0); | |
415 break; | |
416 } | |
417 } | |
418 | |
419 /* Get pan offset of the physical screen. */ | |
420 static uint32_t rivatv_overlay_pan (struct rivatv_info *info){ | |
421 uint32_t pan; | |
422 info->chip.lock (&info->chip, 0); | |
423 VID_WR08 (info->chip.PCIO, 0x3D4, 0x0D); | |
424 pan = VID_RD08 (info->chip.PCIO, 0x3D5); | |
425 VID_WR08 (info->chip.PCIO, 0x3D4, 0x0C); | |
426 pan |= VID_RD08 (info->chip.PCIO, 0x3D5) << 8; | |
427 VID_WR08 (info->chip.PCIO, 0x3D4, 0x19); | |
428 pan |= (VID_RD08 (info->chip.PCIO, 0x3D5) & 0x1F) << 16; | |
429 VID_WR08 (info->chip.PCIO, 0x3D4, 0x2D); | |
430 pan |= (VID_RD08 (info->chip.PCIO, 0x3D5) & 0x60) << 16; | |
431 return pan << 2; | |
432 } | |
433 | |
434 /* Compute and set colorkey depending on the colour depth. */ | |
435 static void rivatv_overlay_colorkey (rivatv_info* info, unsigned int chromakey){ | |
436 uint32_t r, g, b, key = 0; | |
11159 | 437 |
10954 | 438 r = (chromakey & 0x00FF0000) >> 16; |
439 g = (chromakey & 0x0000FF00) >> 8; | |
440 b = chromakey & 0x000000FF; | |
441 switch (info->depth) { | |
442 case 15: | |
11160
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
443 key = ((r >> 3) << 10) | ((g >> 3) << 5) | ((b >> 3)); |
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
444 #ifndef WIN32 |
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
445 key = key | 0x00008000; |
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
446 #endif |
10954 | 447 break; |
11118
344052fdfc4a
Fix colorkey for xvidix, tested on Riva128 4MB X@15/16/24bpp (aka 15/15/32 in nvidia_vid)
atmos4
parents:
11086
diff
changeset
|
448 case 16: // XXX unchecked |
11160
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
449 key = ((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3)); |
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
450 #ifndef WIN32 |
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
451 key = key | 0x00008000; |
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
452 #endif |
10954 | 453 break; |
11160
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
454 case 24: // XXX unchecked, maybe swap order of masking - FIXME Can the card be in 24 bit mode anyway? |
11118
344052fdfc4a
Fix colorkey for xvidix, tested on Riva128 4MB X@15/16/24bpp (aka 15/15/32 in nvidia_vid)
atmos4
parents:
11086
diff
changeset
|
455 key = (chromakey & 0x00FFFFFF) | 0x00800000; |
10954 | 456 break; |
457 case 32: | |
11160
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
458 key = chromakey; |
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
459 #ifndef WIN32 |
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
460 key = key | 0x80000000; |
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
461 #endif |
10954 | 462 break; |
463 } | |
11118
344052fdfc4a
Fix colorkey for xvidix, tested on Riva128 4MB X@15/16/24bpp (aka 15/15/32 in nvidia_vid)
atmos4
parents:
11086
diff
changeset
|
464 //printf("[nvidia_vid] depth=%d %08X \n", info->depth, chromakey); |
10954 | 465 switch (info->chip.arch) { |
466 case NV_ARCH_10: | |
467 case NV_ARCH_20: | |
468 case NV_ARCH_30: | |
469 VID_WR32 (info->chip.PVIDEO, 0xB00, key); | |
470 break; | |
471 case NV_ARCH_03: | |
472 case NV_ARCH_04: | |
473 VID_WR32 (info->chip.PVIDEO, 0x240, key); | |
474 break; | |
475 } | |
476 } | |
477 | |
11085 | 478 static void nv_getscreenproperties(struct rivatv_info *info){ |
479 uint32_t bpp=0; | |
480 info->chip.lock(&info->chip, 0); | |
481 /*get screen depth*/ | |
482 VID_WR08(info->chip.PCIO, 0x03D4,0x28); | |
11783 | 483 bpp = VID_RD08(info->chip.PCIO,0x03D5)&0x3; |
11085 | 484 if(bpp==3)bpp=4; |
485 if((bpp == 2) && (info->chip.PVIDEO[0x00000600/4] & 0x00001000) == 0x0)info->depth=15; | |
486 else info->depth = bpp*8; | |
487 /*get screen width*/ | |
488 VID_WR08(info->chip.PCIO, 0x03D4, 0x1); | |
489 info->screen_x = (1 + VID_RD08(info->chip.PCIO, 0x3D5)) * 8; | |
490 /*get screen height*/ | |
491 /* get first 8 bits in VT_DISPLAY_END*/ | |
492 VID_WR08(info->chip.PCIO, 0x03D4, 0x12); | |
493 info->screen_y = VID_RD08(info->chip.PCIO,0x03D5); | |
494 VID_WR08(info->chip.PCIO,0x03D4,0x07); | |
495 /* get 9th bit in CRTC_OVERFLOW*/ | |
496 info->screen_y |= (VID_RD08(info->chip.PCIO,0x03D5) &0x02)<<7; | |
497 /* and the 10th in CRTC_OVERFLOW*/ | |
498 info->screen_y |=(VID_RD08(info->chip.PCIO,0x03D5) &0x40)<<3; | |
499 ++info->screen_y; | |
500 } | |
501 | |
502 | |
503 | |
10954 | 504 |
505 /* Start overlay video. */ | |
506 void rivatv_overlay_start (struct rivatv_info *info,int bufno){ | |
11085 | 507 uint32_t base, size, offset, xscale, yscale, pan; |
11086 | 508 uint32_t value; |
11233 | 509 int x=info->wx?info->wx:8, y=info->wy?info->wy:8; |
10954 | 510 int lwidth=info->d_width, lheight=info->d_height; |
511 int bps; | |
11783 | 512 int i; |
10954 | 513 |
10977
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
514 size = info->buffer_size; |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
515 base = info->picture_offset; |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
516 offset = bufno*size; |
10954 | 517 /*update depth & dimensions here because it may change with vo vesa or vo fbdev*/ |
11085 | 518 nv_getscreenproperties(info); |
519 | |
520 if(info->depth){ | |
11783 | 521 // bps = info->screen_x * ((info->depth+1)/8); |
10977
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
522 /* get pan offset of the physical screen */ |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
523 pan = rivatv_overlay_pan (info); |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
524 /* adjust window position depending on the pan offset */ |
11783 | 525 bps = 0; |
526 info->chip.lock (&info->chip, 0); | |
527 for (i = 0; (i < 1024) && (bps == 0); i++) | |
528 { | |
529 if (info->chip.arch != NV_ARCH_03) | |
530 bps = info->chip.PGRAPH[0x00000670/4]; | |
531 else | |
532 bps = info->chip.PGRAPH[0x00000650/4]; | |
533 } | |
534 if (bps == 0) | |
535 { | |
536 fprintf(stderr, "[nvidia_vid] reading bps returned 0!!!\n"); | |
537 if (info->bps != 0) | |
538 bps = info->bps; | |
539 } | |
540 else | |
541 { | |
542 info->bps = bps; | |
543 } | |
544 | |
545 if (bps != 0) | |
546 { | |
547 x = info->wx - (pan % bps) * 8 / info->depth; | |
10977
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
548 y = info->wy - (pan / bps); |
11783 | 549 } |
550 } | |
551 | |
10977
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
552 /* adjust negative output window variables */ |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
553 if (x < 0) { |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
554 lwidth = info->d_width + x; |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
555 offset += (-x * info->width / info->d_width) << 1; |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
556 // offset += (-window->x * port->vld_width / window->width) << 1; |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
557 x = 0; |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
558 } |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
559 if (y < 0) { |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
560 lheight = info->d_height + y; |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
561 offset += (-y * info->height / info->d_height * info->width) << 1; |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
562 // offset += (-window->y * port->vld_height / window->height * port->org_width) << 1; |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
563 y = 0; |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
564 } |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
565 |
10954 | 566 switch (info->chip.arch) { |
567 case NV_ARCH_10: | |
568 case NV_ARCH_20: | |
569 case NV_ARCH_30: | |
570 | |
571 /* NV_PVIDEO_BASE */ | |
11160
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
572 VID_WR32 (info->chip.PVIDEO, 0x900 + 0, base + offset); |
10954 | 573 //VID_WR32 (info->chip.PVIDEO, 0x900 + 4, base); |
574 /* NV_PVIDEO_LIMIT */ | |
11160
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
575 VID_WR32 (info->chip.PVIDEO, 0x908 + 0, base + offset + size - 1); |
10954 | 576 //VID_WR32 (info->chip.PVIDEO, 0x908 + 4, base + size - 1); |
577 | |
578 /* extra code for NV20 && NV30 architectures */ | |
579 if (info->chip.arch == NV_ARCH_20 || info->chip.arch == NV_ARCH_30) { | |
11160
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
580 VID_WR32 (info->chip.PVIDEO, 0x800 + 0, base + offset); |
10954 | 581 //VID_WR32 (info->chip.PVIDEO, 0x800 + 4, base); |
11160
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
582 VID_WR32 (info->chip.PVIDEO, 0x808 + 0, base + offset + size - 1); |
10954 | 583 //VID_WR32 (info->chip.PVIDEO, 0x808 + 4, base + size - 1); |
584 } | |
585 | |
586 /* NV_PVIDEO_LUMINANCE */ | |
587 VID_WR32 (info->chip.PVIDEO, 0x910 + 0, 0x00001000); | |
588 //VID_WR32 (info->chip.PVIDEO, 0x910 + 4, 0x00001000); | |
589 /* NV_PVIDEO_CHROMINANCE */ | |
590 VID_WR32 (info->chip.PVIDEO, 0x918 + 0, 0x00001000); | |
591 //VID_WR32 (info->chip.PVIDEO, 0x918 + 4, 0x00001000); | |
592 | |
593 /* NV_PVIDEO_OFFSET */ | |
11160
b5a3ef555164
double buffering fix for cards > NV04 && windows colorkeying fix
faust3
parents:
11159
diff
changeset
|
594 VID_WR32 (info->chip.PVIDEO, 0x920 + 0, 0x0); |
10954 | 595 //VID_WR32 (info->chip.PVIDEO, 0x920 + 4, offset + pitch); |
596 /* NV_PVIDEO_SIZE_IN */ | |
597 VID_WR32 (info->chip.PVIDEO, 0x928 + 0, ((info->height) << 16) | info->width); | |
598 //VID_WR32 (info->chip.PVIDEO, 0x928 + 4, ((port->org_height/2) << 16) | port->org_width); | |
599 /* NV_PVIDEO_POINT_IN */ | |
600 VID_WR32 (info->chip.PVIDEO, 0x930 + 0, 0x00000000); | |
601 //VID_WR32 (info->chip.PVIDEO, 0x930 + 4, 0x00000000); | |
602 /* NV_PVIDEO_DS_DX_RATIO */ | |
603 VID_WR32 (info->chip.PVIDEO, 0x938 + 0, (info->width << 20) / info->d_width); | |
604 //VID_WR32 (info->chip.PVIDEO, 0x938 + 4, (port->org_width << 20) / window->width); | |
605 /* NV_PVIDEO_DT_DY_RATIO */ | |
606 VID_WR32 (info->chip.PVIDEO, 0x940 + 0, ((info->height) << 20) / info->d_height); | |
607 //VID_WR32 (info->chip.PVIDEO, 0x940 + 4, ((port->org_height/2) << 20) / window->height); | |
608 | |
609 /* NV_PVIDEO_POINT_OUT */ | |
610 VID_WR32 (info->chip.PVIDEO, 0x948 + 0, ((y + 0) << 16) | x); | |
611 //VID_WR32 (info->chip.PVIDEO, 0x948 + 4, ((y + 0) << 16) | x); | |
612 /* NV_PVIDEO_SIZE_OUT */ | |
613 VID_WR32 (info->chip.PVIDEO, 0x950 + 0, (lheight << 16) | lwidth); | |
614 //VID_WR32 (info->chip.PVIDEO, 0x950 + 4, (height << 16) | width); | |
615 | |
616 /* NV_PVIDEO_FORMAT */ | |
11086 | 617 value = info->pitch; |
618 if(info->use_colorkey)value |= 1 << 20; | |
619 if(info->format == IMGFMT_YUY2)value |= 1 << 16; | |
620 VID_WR32 (info->chip.PVIDEO, 0x958 + 0, value); | |
621 //VID_WR32 (info->chip.PVIDEO, 0x958 + 4, (pitch << 1) | 0x00100000); | |
10954 | 622 |
623 /* NV_PVIDEO_INTR_EN_BUFFER */ | |
11086 | 624 // VID_OR32 (info->chip.PVIDEO, 0x140, 0x01/*0x11*/); |
10954 | 625 /* NV_PVIDEO_STOP */ |
11086 | 626 VID_WR32 (info->chip.PVIDEO, 0x704,0x0); |
10954 | 627 /* NV_PVIDEO_BUFFER */ |
11086 | 628 VID_WR32 (info->chip.PVIDEO, 0x700, 0x01/*0x11*/); |
10954 | 629 break; |
630 | |
631 case NV_ARCH_03: | |
632 case NV_ARCH_04: | |
633 | |
634 | |
635 /* NV_PVIDEO_OE_STATE */ | |
636 VID_WR32 (info->chip.PVIDEO, 0x224, 0); | |
637 /* NV_PVIDEO_SU_STATE */ | |
638 VID_WR32 (info->chip.PVIDEO, 0x228, 0); | |
639 /* NV_PVIDEO_RM_STATE */ | |
640 VID_WR32 (info->chip.PVIDEO, 0x22C, 0); | |
641 | |
642 /* NV_PVIDEO_BUFF0_START_ADDRESS */ | |
643 VID_WR32 (info->chip.PVIDEO, 0x20C + 0, base + offset + 0); | |
644 VID_WR32 (info->chip.PVIDEO, 0x20C + 4, base + offset + 0); | |
645 /* NV_PVIDEO_BUFF0_PITCH_LENGTH */ | |
646 VID_WR32 (info->chip.PVIDEO, 0x214 + 0, info->pitch); | |
647 VID_WR32 (info->chip.PVIDEO, 0x214 + 4, info->pitch); | |
648 | |
649 /* NV_PVIDEO_WINDOW_START */ | |
650 VID_WR32 (info->chip.PVIDEO, 0x230, (y << 16) | x); | |
651 /* NV_PVIDEO_WINDOW_SIZE */ | |
652 VID_WR32 (info->chip.PVIDEO, 0x234, (lheight << 16) | lwidth); | |
653 /* NV_PVIDEO_STEP_SIZE */ | |
654 yscale = ((info->height - 1) << 11) / (info->d_height - 1); | |
655 xscale = ((info->width - 1) << 11) / (info->d_width - 1); | |
656 VID_WR32 (info->chip.PVIDEO, 0x200, (yscale << 16) | xscale); | |
657 | |
658 /* NV_PVIDEO_RED_CSC_OFFSET */ | |
659 VID_WR32 (info->chip.PVIDEO, 0x280, 0x69); | |
660 /* NV_PVIDEO_GREEN_CSC_OFFSET */ | |
661 VID_WR32 (info->chip.PVIDEO, 0x284, 0x3e); | |
662 /* NV_PVIDEO_BLUE_CSC_OFFSET */ | |
663 VID_WR32 (info->chip.PVIDEO, 0x288, 0x89); | |
664 /* NV_PVIDEO_CSC_ADJUST */ | |
665 VID_WR32 (info->chip.PVIDEO, 0x28C, 0x00000); /* No colour correction! */ | |
666 | |
667 /* NV_PVIDEO_CONTROL_Y (BLUR_ON, LINE_HALF) */ | |
668 VID_WR32 (info->chip.PVIDEO, 0x204, 0x001); | |
669 /* NV_PVIDEO_CONTROL_X (WEIGHT_HEAVY, SHARPENING_ON, SMOOTHING_ON) */ | |
11086 | 670 VID_WR32 (info->chip.PVIDEO, 0x208, 0x111); /*directx overlay 0x110 */ |
10954 | 671 |
672 /* NV_PVIDEO_FIFO_BURST_LENGTH */ | |
673 VID_WR32 (info->chip.PVIDEO, 0x23C, 0x03); | |
674 /* NV_PVIDEO_FIFO_THRES_SIZE */ | |
675 VID_WR32 (info->chip.PVIDEO, 0x238, 0x38); /*windows uses 0x40*/ | |
676 | |
677 /* NV_PVIDEO_BUFF0_OFFSET */ | |
678 VID_WR32 (info->chip.PVIDEO, 0x21C + 0, 0); | |
679 VID_WR32 (info->chip.PVIDEO, 0x21C + 4, 0); | |
680 | |
681 /* NV_PVIDEO_INTR_EN_0_NOTIFY_ENABLED */ | |
682 // VID_OR32 (info->chip.PVIDEO, 0x140, 0x01); | |
11086 | 683 |
10954 | 684 /* NV_PVIDEO_OVERLAY (KEY_ON, VIDEO_ON, FORMAT_CCIR) */ |
11086 | 685 value = 0x1; /*video on*/ |
686 if(info->format==IMGFMT_YUY2)value |= 0x100; | |
687 if(info->use_colorkey)value |=0x10; | |
688 VID_WR32 (info->chip.PVIDEO, 0x244, value); | |
689 | |
10954 | 690 /* NV_PVIDEO_SU_STATE */ |
691 VID_XOR32 (info->chip.PVIDEO, 0x228, 1 << 16); | |
692 break; | |
693 } | |
694 /*set colorkey*/ | |
695 rivatv_overlay_colorkey(info,info->vidixcolorkey); | |
696 | |
697 } | |
698 | |
699 | |
10977
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
700 |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
701 |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
702 |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
703 |
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
704 |
10954 | 705 static rivatv_info* info; |
706 | |
707 | |
708 | |
709 | |
710 int vixInit(void){ | |
711 int mtrr; | |
712 info = (rivatv_info*)calloc(1,sizeof(rivatv_info)); | |
713 info->control_base = map_phys_mem(pci_info.base0, 0x00C00000 + 0x00008000); | |
714 info->chip.arch = nvidia_card_ids[find_chip(pci_info.device)].arch; | |
715 printf("[nvidia_vid] arch %x register base %x\n",info->chip.arch,(unsigned int)info->control_base); | |
716 info->chip.PFIFO = (uint32_t *) (info->control_base + 0x00002000); | |
717 info->chip.FIFO = (uint32_t *) (info->control_base + 0x00800000); | |
718 info->chip.PMC = (uint32_t *) (info->control_base + 0x00000000); | |
719 info->chip.PFB = (uint32_t *) (info->control_base + 0x00100000); | |
720 info->chip.PME = (uint32_t *) (info->control_base + 0x00000000); | |
721 info->chip.PCIO = (uint8_t *) (info->control_base + 0x00601000); | |
722 info->chip.PVIO = (uint8_t *) (info->control_base + 0x000C0000); | |
723 info->chip.PGRAPH = (uint32_t *) (info->control_base + 0x00400000); | |
724 /* setup chip specific functions */ | |
725 switch (info->chip.arch) { | |
726 case NV_ARCH_03: | |
727 info->chip.lock = rivatv_lock_nv03; | |
728 info->chip.fbsize = rivatv_fbsize_nv03 (&info->chip); | |
729 info->chip.PVIDEO = (uint32_t *) (info->control_base + 0x00680000); | |
730 break; | |
731 case NV_ARCH_04: | |
732 info->chip.lock = rivatv_lock_nv04; | |
733 info->chip.fbsize = rivatv_fbsize_nv04 (&info->chip); | |
734 info->chip.PRAMIN = (uint32_t *) (info->control_base + 0x00700000); | |
735 info->chip.PVIDEO = (uint32_t *) (info->control_base + 0x00680000); | |
736 break; | |
737 case NV_ARCH_10: | |
738 case NV_ARCH_20: | |
739 case NV_ARCH_30: | |
740 info->chip.lock = rivatv_lock_nv04; | |
741 info->chip.fbsize = rivatv_fbsize_nv10 (&info->chip); | |
742 info->chip.PRAMIN = (uint32_t *) (info->control_base + 0x00700000); | |
743 info->chip.PVIDEO = (uint32_t *) (info->control_base + 0x00008000); | |
744 break; | |
745 } | |
746 switch (info->chip.arch) { | |
747 case NV_ARCH_03: | |
748 { | |
749 /* This maps framebuffer @6MB, thus 2MB are left for video. */ | |
750 info->video_base = map_phys_mem(pci_info.base1, info->chip.fbsize); | |
751 /* This may trash your screen for resolutions greater than 1024x768, sorry. */ | |
10977
3da6b1de1c33
make it work in textmode again && support for nv03 with 4MB RAM
faust3
parents:
10970
diff
changeset
|
752 info->picture_offset = 1024*768* 4 * ((info->chip.fbsize > 4194304)?2:1); |
10954 | 753 info->picture_base = (uint32_t) info->video_base + info->picture_offset; |
754 info->chip.PRAMIN = (uint32_t *) (info->video_base + 0x00C00000); | |
755 break; | |
756 } | |
757 case NV_ARCH_04: | |
758 case NV_ARCH_10: | |
759 case NV_ARCH_20: | |
760 case NV_ARCH_30: | |
761 { | |
762 info->video_base = map_phys_mem(pci_info.base1, info->chip.fbsize); | |
763 info->picture_offset = info->chip.fbsize - NV04_BES_SIZE; | |
764 // info->picture_base = (unsigned long)map_phys_mem(pci_info.base1+info->picture_offset,NV04_BES_SIZE); | |
765 info->picture_base = (uint32_t) info->video_base + info->picture_offset; | |
766 break; | |
767 } | |
768 } | |
769 | |
770 printf("[nvidia_vid] detected memory size %u MB\n",(uint32_t)(info->chip.fbsize /1024/1024)); | |
771 | |
772 if ((mtrr = mtrr_set_type(pci_info.base1, info->chip.fbsize, MTRR_TYPE_WRCOMB))!= 0) | |
11085 | 773 printf("[nvidia_vid] unable to setup MTRR: %s\n", strerror(mtrr)); |
10954 | 774 else |
11085 | 775 printf("[nvidia_vid] MTRR set up\n"); |
10954 | 776 |
11085 | 777 nv_getscreenproperties(info); |
778 if(!info->depth)printf("[nvidia_vid] text mode: %ux%u\n",info->screen_x,info->screen_y); | |
779 else printf("[nvidia_vid] video mode: %ux%u@%u\n",info->screen_x,info->screen_y, info->depth); | |
780 | |
10954 | 781 |
782 rivatv_enable_PMEDIA(info); | |
11783 | 783 info->cur_frame = 0; |
11159 | 784 info->use_colorkey = 0; |
11783 | 785 |
10954 | 786 return 0; |
787 } | |
788 | |
789 void vixDestroy(void){ | |
790 unmap_phys_mem(info->control_base ,0x00C00000 + 0x00008000); | |
791 unmap_phys_mem(info->video_base, info->chip.fbsize); | |
792 free(info); | |
793 } | |
794 | |
795 int vixGetCapability(vidix_capability_t *to){ | |
796 memcpy(to, &nvidia_cap, sizeof(vidix_capability_t)); | |
797 return 0; | |
798 } | |
799 | |
800 inline static int is_supported_fourcc(uint32_t fourcc) | |
801 { | |
11086 | 802 if (fourcc == IMGFMT_UYVY || fourcc == IMGFMT_YUY2) |
10954 | 803 return 1; |
804 else | |
805 return 0; | |
806 } | |
807 | |
808 int vixQueryFourcc(vidix_fourcc_t *to){ | |
809 if(is_supported_fourcc(to->fourcc)){ | |
810 to->depth = VID_DEPTH_1BPP | VID_DEPTH_2BPP | | |
811 VID_DEPTH_4BPP | VID_DEPTH_8BPP | | |
812 VID_DEPTH_12BPP| VID_DEPTH_15BPP| | |
813 VID_DEPTH_16BPP| VID_DEPTH_24BPP| | |
814 VID_DEPTH_32BPP; | |
815 to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; | |
816 return 0; | |
817 } | |
818 else to->depth = to->flags = 0; | |
819 return ENOSYS; | |
820 } | |
821 | |
822 int vixConfigPlayback(vidix_playback_t *vinfo){ | |
823 uint32_t i; | |
824 printf("called %s\n", __FUNCTION__); | |
825 if (! is_supported_fourcc(vinfo->fourcc)) | |
826 return ENOSYS; | |
827 | |
828 info->width = vinfo->src.w; | |
829 info->height = vinfo->src.h; | |
830 | |
831 info->d_width = vinfo->dest.w; | |
832 info->d_height = vinfo->dest.h; | |
833 info->wx = vinfo->dest.x; | |
834 info->wy = vinfo->dest.y; | |
835 info->format = vinfo->fourcc; | |
836 | |
837 printf("[nvidia_vid] setting up a %dx%d-%dx%d video window (src %dx%d), format 0x%X\n", | |
838 info->d_width, info->d_height, info->wx, info->wy, info->width, info->height, vinfo->fourcc); | |
839 | |
840 | |
841 vinfo->dga_addr=(void*)(info->picture_base); | |
842 | |
843 switch (vinfo->fourcc) | |
844 { | |
845 case IMGFMT_YUY2: | |
846 case IMGFMT_UYVY: | |
847 | |
11086 | 848 vinfo->dest.pitch.y = 16; |
10954 | 849 vinfo->dest.pitch.u = 0; |
850 vinfo->dest.pitch.v = 0; | |
851 | |
852 vinfo->offset.y = 0; | |
853 vinfo->offset.v = 0; | |
854 vinfo->offset.u = 0; | |
11902 | 855 info->pitch = ((info->width << 1) + (vinfo->dest.pitch.y-1)) & ~(vinfo->dest.pitch.y-1); |
10954 | 856 vinfo->frame_size = info->pitch * info->height; |
857 break; | |
858 } | |
859 info->buffer_size = vinfo->frame_size; | |
860 info->num_frames = vinfo->num_frames= (info->chip.fbsize - info->picture_offset)/vinfo->frame_size; | |
861 if(vinfo->num_frames > MAX_FRAMES)vinfo->num_frames = MAX_FRAMES; | |
862 // vinfo->num_frames = 1; | |
863 // printf("[nvidia_vid] Number of frames %i\n",vinfo->num_frames); | |
864 for(i=0;i <vinfo->num_frames;i++)vinfo->offsets[i] = vinfo->frame_size*i; | |
865 return 0; | |
866 } | |
867 | |
868 int vixPlaybackOn(void){ | |
11783 | 869 rivatv_overlay_start(info,info->cur_frame); |
10954 | 870 return 0; |
871 } | |
872 | |
873 int vixPlaybackOff(void){ | |
874 rivatv_overlay_stop(info); | |
875 return 0; | |
876 } | |
877 | |
878 int vixSetGrKeys( const vidix_grkey_t * grkey){ | |
11159 | 879 if (grkey->ckey.op == CKEY_FALSE) |
880 { | |
881 info->use_colorkey = 0; | |
882 printf("[nvidia_vid] colorkeying disabled\n"); | |
883 } | |
11165 | 884 else { |
11159 | 885 info->use_colorkey = 1; |
10954 | 886 info->vidixcolorkey = ((grkey->ckey.red<<16)|(grkey->ckey.green<<8)|grkey->ckey.blue); |
887 printf("[nvidia_vid] set colorkey 0x%x\n",info->vidixcolorkey); | |
11165 | 888 } |
11210 | 889 if(info->d_width && info->d_height)rivatv_overlay_start(info,0); |
10954 | 890 return 0; |
891 } | |
892 | |
893 int vixPlaybackFrameSelect(unsigned int frame){ | |
894 // printf("selecting buffer %d\n", frame); | |
895 rivatv_overlay_start(info, frame); | |
896 if (info->num_frames >= 1) | |
11783 | 897 info->cur_frame = frame/*(frame+1)%info->num_frames*/; |
10954 | 898 return 0; |
899 } |