7 #include "xf86_OSproc.h"
8 #include "xf86Resources.h"
10 #include "xf86PciInfo.h"
12 #include "xf86fbman.h"
13 #include "regionstr.h"
16 #include <X11/extensions/Xv.h>
19 #include "dixstruct.h"
22 #include "nv_include.h"
25 #define IMAGE_MAX_W 2046
26 #define IMAGE_MAX_H 2046
28 #define OFF_DELAY 500 /* milliseconds */
29 #define FREE_DELAY 5000
31 #define OFF_TIMER 0x01
32 #define FREE_TIMER 0x02
33 #define CLIENT_VIDEO_ON 0x04
35 #define TIMER_MASK (OFF_TIMER | FREE_TIMER)
37 #define NUM_BLIT_PORTS 32
39 /* Value taken by pPriv -> currentHostBuffer when we failed to allocate the two private buffers in TT memory, so that we can catch this case
40 and attempt no other allocation afterwards (performance reasons) */
41 #define NO_PRIV_HOST_BUFFER_AVAILABLE 9999
43 typedef struct _NVPortPrivRec {
50 Bool autopaintColorKey;
59 NVAllocRec * video_mem;
62 NVAllocRec * TT_mem_chunk[2];
63 int currentHostBuffer;
64 struct drm_nouveau_notifierobj_alloc *DMANotifier[2];
65 } NVPortPrivRec, *NVPortPrivPtr;
68 /* Xv DMA notifiers status tracing */
71 XV_DMA_NOTIFIER_NOALLOC=0, //notifier not allocated
72 XV_DMA_NOTIFIER_INUSE=1,
73 XV_DMA_NOTIFIER_FREE=2, //notifier allocated, ready for use
76 /* We have six notifiers available, they are not allocated at startup */
77 int XvDMANotifierStatus[6]= { XV_DMA_NOTIFIER_NOALLOC , XV_DMA_NOTIFIER_NOALLOC , XV_DMA_NOTIFIER_NOALLOC ,
78 XV_DMA_NOTIFIER_NOALLOC , XV_DMA_NOTIFIER_NOALLOC , XV_DMA_NOTIFIER_NOALLOC };
79 struct drm_nouveau_notifierobj_alloc * XvDMANotifiers[6];
81 /* NVPutImage action flags */
88 IS_RGB=32, //I am not sure how long we will support it
91 #define GET_OVERLAY_PRIVATE(pNv) \
92 (NVPortPrivPtr)((pNv)->overlayAdaptor->pPortPrivates[0].ptr)
94 #define GET_BLIT_PRIVATE(pNv) \
95 (NVPortPrivPtr)((pNv)->blitAdaptor->pPortPrivates[0].ptr)
97 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
99 static Atom xvBrightness, xvContrast, xvColorKey, xvSaturation,
100 xvHue, xvAutopaintColorKey, xvSetDefaults, xvDoubleBuffer,
101 xvITURBT709, xvSyncToVBlank;
103 /* client libraries expect an encoding */
104 static XF86VideoEncodingRec DummyEncoding =
108 IMAGE_MAX_W, IMAGE_MAX_H,
112 #define NUM_FORMATS_ALL 6
114 XF86VideoFormatRec NVFormats[NUM_FORMATS_ALL] =
116 {15, TrueColor}, {16, TrueColor}, {24, TrueColor},
117 {15, DirectColor}, {16, DirectColor}, {24, DirectColor}
120 #define NUM_NV04_OVERLAY_ATTRIBUTES 1
121 XF86AttributeRec NV04OverlayAttributes[NUM_NV04_OVERLAY_ATTRIBUTES] =
123 {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
127 #define NUM_OVERLAY_ATTRIBUTES 9
128 XF86AttributeRec NVOverlayAttributes[NUM_OVERLAY_ATTRIBUTES] =
130 {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"},
131 {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
132 {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"},
133 {XvSettable , 0, 0, "XV_SET_DEFAULTS"},
134 {XvSettable | XvGettable, -512, 511, "XV_BRIGHTNESS"},
135 {XvSettable | XvGettable, 0, 8191, "XV_CONTRAST"},
136 {XvSettable | XvGettable, 0, 8191, "XV_SATURATION"},
137 {XvSettable | XvGettable, 0, 360, "XV_HUE"},
138 {XvSettable | XvGettable, 0, 1, "XV_ITURBT_709"}
141 #define NUM_BLIT_ATTRIBUTES 2
142 XF86AttributeRec NVBlitAttributes[NUM_BLIT_ATTRIBUTES] =
144 {XvSettable , 0, 0, "XV_SET_DEFAULTS"},
145 {XvSettable | XvGettable, 0, 1, "XV_SYNC_TO_VBLANK"}
149 #define NUM_IMAGES_YUV 4
150 #define NUM_IMAGES_ALL 5
152 #define FOURCC_RGB 0x0000003
153 #define XVIMAGE_RGB \
158 { 0x03, 0x00, 0x00, 0x00, \
159 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
163 24, 0x00ff0000, 0x0000ff00, 0x000000ff, \
168 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, \
172 static XF86ImageRec NVImages[NUM_IMAGES_ALL] =
182 NVWaitVSync(ScrnInfoPtr pScrn)
184 NVPtr pNv = NVPTR(pScrn);
186 BEGIN_RING(NvImageBlit, 0x0000012C, 1);
188 BEGIN_RING(NvImageBlit, 0x00000134, 1);
189 /* If crtc1 is active, this will produce one, otherwise zero */
190 /* The assumption is that at least one is active */
191 OUT_RING (pNv->crtc_active[1]);
192 BEGIN_RING(NvImageBlit, 0x00000100, 1);
194 BEGIN_RING(NvImageBlit, 0x00000130, 1);
200 * set attributes of port "pPriv" to compiled-in (except for colorKey) defaults
202 * @param pScrn screen to get the default colorKey from
203 * @param pPriv port to reset to defaults
206 NVSetPortDefaults (ScrnInfoPtr pScrn, NVPortPrivPtr pPriv)
208 NVPtr pNv = NVPTR(pScrn);
210 pPriv->brightness = 0;
211 pPriv->contrast = 4096;
212 pPriv->saturation = 4096;
214 pPriv->colorKey = pNv->videoKey;
215 pPriv->autopaintColorKey = TRUE;
216 pPriv->doubleBuffer = TRUE;
217 pPriv->iturbt_709 = FALSE;
218 pPriv->currentHostBuffer = 0;
223 * writes the current attributes from the overlay port to the hardware
226 NVResetVideo (ScrnInfoPtr pScrn)
228 NVPtr pNv = NVPTR(pScrn);
229 NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
230 int satSine, satCosine;
233 angle = (double)pPriv->hue * 3.1415927 / 180.0;
235 satSine = pPriv->saturation * sin(angle);
238 satCosine = pPriv->saturation * cos(angle);
239 if (satCosine < -1024)
242 nvWriteVIDEO(pNv, NV_PVIDEO_LUMINANCE(0), (pPriv->brightness << 16) |
244 nvWriteVIDEO(pNv, NV_PVIDEO_LUMINANCE(1), (pPriv->brightness << 16) |
246 nvWriteVIDEO(pNv, NV_PVIDEO_CHROMINANCE(0), (satSine << 16) |
247 (satCosine & 0xffff));
248 nvWriteVIDEO(pNv, NV_PVIDEO_CHROMINANCE(1), (satSine << 16) |
249 (satCosine & 0xffff));
250 nvWriteVIDEO(pNv, NV_PVIDEO_COLOR_KEY, pPriv->colorKey);
255 * Tell the hardware to stop the overlay
258 NVStopOverlay (ScrnInfoPtr pScrn)
260 NVPtr pNv = NVPTR(pScrn);
262 if ( pNv -> Architecture != NV_ARCH_04 )
263 nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 1);
266 nvWriteRAMDAC(pNv, 0, 0x244, nvReadRAMDAC(pNv, 0, 0x244) &~ 0x1);
267 nvWriteRAMDAC(pNv, 0, 0x224, 0);
268 nvWriteRAMDAC(pNv, 0, 0x228, 0);
269 nvWriteRAMDAC(pNv, 0, 0x22c, 0);
274 * NVXvDMANotifierAlloc
275 * allocates a notifier from the table of 6 we have
277 * @return a notifier instance or NULL on error
279 static struct drm_nouveau_notifierobj_alloc * NVXvDMANotifierAlloc(ScrnInfoPtr pScrn)
282 for ( i = 0; i < 6; i ++ )
284 if ( XvDMANotifierStatus[i] == XV_DMA_NOTIFIER_INUSE )
287 if ( XvDMANotifierStatus[i] == XV_DMA_NOTIFIER_FREE )
289 XvDMANotifierStatus[i] = XV_DMA_NOTIFIER_INUSE;
290 return XvDMANotifiers[i];
293 if ( XvDMANotifierStatus[i] == XV_DMA_NOTIFIER_NOALLOC )
295 XvDMANotifiers[i] = NVNotifierAlloc(pScrn, NvDmaXvNotifier0 + i);
296 if (XvDMANotifiers[i])
298 XvDMANotifierStatus[i] = XV_DMA_NOTIFIER_INUSE;
299 return XvDMANotifiers[i];
309 * NVXvDMANotifierFree
310 * frees a notifier from the table of 6 we have
314 static void NVXvDMANotifierFree(ScrnInfoPtr pScrn, struct drm_nouveau_notifierobj_alloc * target)
317 for ( i = 0; i < 6; i ++ )
319 if ( XvDMANotifiers[i] == target )
322 XvDMANotifierStatus[i] = XV_DMA_NOTIFIER_FREE;
326 * NVAllocateVideoMemory
327 * allocates video memory for a given port
329 * @param pScrn screen which requests the memory
330 * @param mem pointer to previously allocated memory for reallocation
331 * @param size size of requested memory segment
332 * @return pointer to the allocated memory
335 NVAllocateVideoMemory(ScrnInfoPtr pScrn, NVAllocRec *mem, int size)
337 NVPtr pNv = NVPTR(pScrn);
341 if(mem->size >= size)
343 NVFreeMemory(pNv, mem);
346 return NVAllocateMemory(pNv, NOUVEAU_MEM_FB, size); /* align 32? */
351 * allocates TT memory for a given port
353 * @param pScrn screen which requests the memory
354 * @param mem pointer to previously allocated memory for reallocation
355 * @param size size of requested memory segment
356 * @return pointer to the allocated memory
359 NVAllocateTTMemory(ScrnInfoPtr pScrn, NVAllocRec *mem, int size)
361 NVPtr pNv = NVPTR(pScrn);
365 if(mem->size >= size)
367 NVFreeMemory(pNv, mem);
369 return NVAllocateMemory(pNv, NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI_ACCEPTABLE, size); /* align 32? */
374 * frees memory held by a given port
376 * @param pScrn screen whose port wants to free memory
377 * @param pPriv port to free memory of
380 NVFreePortMemory(ScrnInfoPtr pScrn, NVPortPrivPtr pPriv)
382 NVPtr pNv = NVPTR(pScrn);
384 //xf86DrvMsg(0, X_INFO, "Freeing port memory - TTmem chunks %p %p, notifiers %p %p\n", pPriv->TT_mem_chunk[0], pPriv->TT_mem_chunk[1], pPriv->DMANotifier[0], pPriv->DMANotifier[1]);
386 if(pPriv->video_mem) {
387 NVFreeMemory(pNv, pPriv->video_mem);
388 pPriv->video_mem = NULL;
391 if ( pPriv->TT_mem_chunk[ 0 ] && pPriv->DMANotifier [ 0 ] )
393 NVNotifierWaitStatus(pScrn, pPriv->DMANotifier [ 0 ] , 0, 1000);
396 if ( pPriv->TT_mem_chunk[ 1 ] && pPriv->DMANotifier [ 1 ] )
398 NVNotifierWaitStatus(pScrn, pPriv->DMANotifier [ 1 ] , 0, 1000);
401 if(pPriv->TT_mem_chunk[0]) {
402 NVFreeMemory(pNv, pPriv->TT_mem_chunk[0]);
403 pPriv->TT_mem_chunk[0] = NULL;
406 if(pPriv->TT_mem_chunk[1]) {
407 NVFreeMemory(pNv, pPriv->TT_mem_chunk[1]);
408 pPriv->TT_mem_chunk[1] = NULL;
411 if(pPriv->DMANotifier[0]) {
412 NVXvDMANotifierFree(pScrn, pPriv->DMANotifier[0]);
413 pPriv->DMANotifier[0] = NULL;
416 if(pPriv->DMANotifier[1]) {
417 NVXvDMANotifierFree(pScrn, pPriv->DMANotifier[1]);
418 pPriv->DMANotifier[1] = NULL;
424 * NVFreeOverlayMemory
425 * frees memory held by the overlay port
427 * @param pScrn screen whose overlay port wants to free memory
430 NVFreeOverlayMemory(ScrnInfoPtr pScrn)
432 NVPtr pNv = NVPTR(pScrn);
433 NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
434 NVFreePortMemory(pScrn, pPriv);
435 nvWriteMC(pNv, 0x200, (nvReadMC(pNv, 0x200) & 0xEFFFFFFF));
436 nvWriteMC(pNv, 0x200, (nvReadMC(pNv, 0x200) | 0x10000000));
441 * frees memory held by the blit port
443 * @param pScrn screen whose blit port wants to free memory
446 NVFreeBlitMemory(ScrnInfoPtr pScrn)
448 NVPtr pNv = NVPTR(pScrn);
449 NVPortPrivPtr pPriv = GET_BLIT_PRIVATE(pNv);
450 NVFreePortMemory(pScrn, pPriv);
454 * NVVideoTimerCallback
455 * callback function which perform cleanup tasks (stop overlay, free memory).
456 * within the driver it is only called once from NVBlockHandler in nv_driver.c
459 NVVideoTimerCallback(ScrnInfoPtr pScrn, Time currentTime)
461 NVPtr pNv = NVPTR(pScrn);
462 NVPortPrivPtr pOverPriv = NULL;
463 NVPortPrivPtr pBlitPriv = NULL;
464 Bool needCallback = FALSE;
469 if (pNv->overlayAdaptor) {
470 pOverPriv = GET_OVERLAY_PRIVATE(pNv);
471 if (!pOverPriv->videoStatus)
475 if (pNv->blitAdaptor) {
476 pBlitPriv = GET_BLIT_PRIVATE(pNv);
477 if (!pBlitPriv->videoStatus)
482 if (pOverPriv->videoTime < currentTime) {
483 if (pOverPriv->videoStatus & OFF_TIMER) {
484 NVStopOverlay(pScrn);
485 pOverPriv->videoStatus = FREE_TIMER;
486 pOverPriv->videoTime = currentTime + FREE_DELAY;
489 if (pOverPriv->videoStatus & FREE_TIMER) {
490 NVFreeOverlayMemory(pScrn);
491 pOverPriv->videoStatus = 0;
499 if (pBlitPriv->videoTime < currentTime) {
500 NVFreeBlitMemory(pScrn);
501 pBlitPriv->videoStatus = 0;
507 pNv->VideoTimerCallback = needCallback ? NVVideoTimerCallback : NULL;
512 * program hardware to overlay image into front buffer
514 * @param pScrn screen
515 * @param offset card offset to the pixel data
516 * @param id format of image
517 * @param dstPitch pitch of the pixel data in VRAM
518 * @param dstBox destination box
519 * @param x1 first source point - x
520 * @param y1 first source point - y
521 * @param x2 second source point - x
522 * @param y2 second source point - y
523 * @param width width of the source image = x2 - x1
524 * @param height height
525 * @param src_w width of the image data in VRAM
526 * @param src_h height
527 * @param drw_w width of the image to draw to screen
528 * @param drw_h height
529 * @param clipBoxes ???
532 NVPutOverlayImage(ScrnInfoPtr pScrn, int offset, int uvoffset, int id,
533 int dstPitch, BoxPtr dstBox,
534 int x1, int y1, int x2, int y2,
535 short width, short height,
536 short src_w, short src_h,
537 short drw_w, short drw_h,
540 NVPtr pNv = NVPTR(pScrn);
541 NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
542 int buffer = pPriv->currentBuffer;
544 /* paint the color key */
545 if(pPriv->autopaintColorKey && (pPriv->grabbedByV4L ||
546 !REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes))) {
547 /* we always paint V4L's color key */
548 if (!pPriv->grabbedByV4L)
549 REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
551 xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
555 if(pNv->CurrentLayout.mode->Flags & V_DBLSCAN) {
561 //xf86DrvMsg(0, X_INFO, "SIZE_IN h %d w %d, POINT_IN x %d y %d, DS_DX %d DT_DY %d, POINT_OUT x %d y %d SIZE_OUT h %d w %d\n", height, width, x1 >> 16,y1>>16, (src_w << 20) / drw_w, (src_h << 20) / drw_h, (dstBox->x1),(dstBox->y1), (dstBox->y2 - dstBox->y1), (dstBox->x2 - dstBox->x1));
563 nvWriteVIDEO(pNv, NV_PVIDEO_BASE(buffer) , 0);
564 nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(buffer) , offset);
565 nvWriteVIDEO(pNv, NV_PVIDEO_SIZE_IN(buffer) , (height << 16) | width);
566 nvWriteVIDEO(pNv, NV_PVIDEO_POINT_IN(buffer) ,
567 ((y1 << 4) & 0xffff0000) | (x1 >> 12));
568 nvWriteVIDEO(pNv, NV_PVIDEO_DS_DX(buffer) , (src_w << 20) / drw_w);
569 nvWriteVIDEO(pNv, NV_PVIDEO_DT_DY(buffer) , (src_h << 20) / drw_h);
570 nvWriteVIDEO(pNv, NV_PVIDEO_POINT_OUT(buffer),
571 (dstBox->y1 << 16) | dstBox->x1);
572 nvWriteVIDEO(pNv, NV_PVIDEO_SIZE_OUT(buffer) ,
573 ((dstBox->y2 - dstBox->y1) << 16) |
574 (dstBox->x2 - dstBox->x1));
576 dstPitch |= NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY; /* use color key */
577 if(id != FOURCC_UYVY)
578 dstPitch |= NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8;
579 if(pPriv->iturbt_709)
580 dstPitch |= NV_PVIDEO_FORMAT_MATRIX_ITURBT709;
582 if( id == FOURCC_YV12 || id == FOURCC_I420 )
583 dstPitch |= NV_PVIDEO_FORMAT_PLANAR;
585 /* Those are important only for planar formats (NV12) */
588 nvWriteVIDEO(pNv, NV_PVIDEO_UVPLANE_BASE(buffer), 0);
589 nvWriteVIDEO(pNv, NV_PVIDEO_UVPLANE_OFFSET_BUFF(buffer), uvoffset);
592 nvWriteVIDEO(pNv, NV_PVIDEO_FORMAT(buffer), dstPitch);
593 nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 0);
594 nvWriteVIDEO(pNv, NV_PVIDEO_BUFFER, buffer ? 0x10 : 0x1);
596 pPriv->videoStatus = CLIENT_VIDEO_ON;
600 NV04PutOverlayImage(ScrnInfoPtr pScrn, int offset, int id,
601 int dstPitch, BoxPtr dstBox,
602 int x1, int y1, int x2, int y2,
603 short width, short height,
604 short src_w, short src_h,
605 short drw_w, short drw_h,
608 NVPtr pNv = NVPTR(pScrn);
609 NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
611 /* paint the color key */
612 if(pPriv->autopaintColorKey && (pPriv->grabbedByV4L ||
613 !REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes))) {
614 /* we always paint V4L's color key */
615 if (!pPriv->grabbedByV4L)
616 REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
618 xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
622 if(pNv->CurrentLayout.mode->Flags & V_DBLSCAN) { /*This may not work with NV04 overlay according to rivatv source*/
628 /* NV_PVIDEO_OE_STATE */
629 /* NV_PVIDEO_SU_STATE */
630 /* NV_PVIDEO_RM_STATE */
631 nvWriteRAMDAC(pNv, 0, 0x224, 0);
632 nvWriteRAMDAC(pNv, 0, 0x228, 0);
633 nvWriteRAMDAC(pNv, 0, 0x22c, 0);
635 /* NV_PVIDEO_BUFF0_START_ADDRESS */
636 nvWriteRAMDAC(pNv, 0, 0x20C, offset);
637 nvWriteRAMDAC(pNv, 0, 0x20C + 4, offset);
638 /* NV_PVIDEO_BUFF0_PITCH_LENGTH */
639 nvWriteRAMDAC(pNv, 0, 0x214, dstPitch);
640 nvWriteRAMDAC(pNv, 0, 0x214 + 4, dstPitch);
642 /* NV_PVIDEO_BUFF0_OFFSET */
643 nvWriteRAMDAC(pNv, 0, 0x21C, 0);
644 nvWriteRAMDAC(pNv, 0, 0x21C + 4, 0);
646 /* NV_PVIDEO_WINDOW_START */
647 nvWriteRAMDAC(pNv, 0, 0x230, (dstBox->y1 << 16) | dstBox->x1);
648 /* NV_PVIDEO_WINDOW_SIZE */
649 nvWriteRAMDAC(pNv, 0, 0x234, ((dstBox->y2 - dstBox->y1) << 16) |
650 (dstBox->x2 - dstBox->x1));
651 /* NV_PVIDEO_STEP_SIZE */
652 nvWriteRAMDAC(pNv, 0, 0x200, (uint32_t)((src_h - 1 << 11) / (drw_h - 1)) << 16 | (uint32_t)((src_w - 1 << 11) / (drw_w - 1)));
654 /* NV_PVIDEO_RED_CSC_OFFSET */
655 /* NV_PVIDEO_GREEN_CSC_OFFSET */
656 /* NV_PVIDEO_BLUE_CSC_OFFSET */
657 /* NV_PVIDEO_CSC_ADJUST */
658 nvWriteRAMDAC(pNv, 0, 0x280, 0x69);
659 nvWriteRAMDAC(pNv, 0, 0x284, 0x3e);
660 nvWriteRAMDAC(pNv, 0, 0x288, 0x89);
661 nvWriteRAMDAC(pNv, 0, 0x28C, 0x0);
663 /* NV_PVIDEO_CONTROL_Y (BLUR_ON, LINE_HALF) */
664 nvWriteRAMDAC(pNv, 0, 0x204, 0x001);
665 /* NV_PVIDEO_CONTROL_X (WEIGHT_HEAVY, SHARPENING_ON, SMOOTHING_ON) */
666 nvWriteRAMDAC(pNv, 0, 0x208, 0x111);
668 /* NV_PVIDEO_FIFO_BURST_LENGTH */
669 nvWriteRAMDAC(pNv, 0, 0x23C, 0x03);
670 /* NV_PVIDEO_FIFO_THRES_SIZE */
671 nvWriteRAMDAC(pNv, 0, 0x238, 0x38);
674 nvWriteRAMDAC(pNv, 0, 0x240, pPriv->colorKey);
680 nvWriteRAMDAC(pNv, 0, 0x244, 0x111);
682 /* NV_PVIDEO_SU_STATE */
683 nvWriteRAMDAC(pNv, 0, 0x228, (nvReadRAMDAC(pNv, 0, 0x228) ^ (1 << 16)));
685 pPriv->videoStatus = CLIENT_VIDEO_ON;
687 #ifndef ExaOffscreenMarkUsed
688 extern void ExaOffscreenMarkUsed(PixmapPtr);
690 #ifndef exaGetDrawablePixmap
691 extern PixmapPtr exaGetDrawablePixmap(DrawablePtr);
693 #ifndef exaPixmapIsOffscreen
694 extern Bool exaPixmapIsOffscreen(PixmapPtr p);
696 /* To support EXA 2.0, 2.1 has this in the header */
697 #ifndef exaMoveInPixmap
698 extern void exaMoveInPixmap(PixmapPtr pPixmap);
704 * @param pScrn screen
706 * @param id colorspace of image
723 NVPutBlitImage(ScrnInfoPtr pScrn, int src_offset, int id,
724 int src_pitch, BoxPtr dstBox,
725 int x1, int y1, int x2, int y2,
726 short width, short height,
727 short src_w, short src_h,
728 short drw_w, short drw_h,
732 NVPtr pNv = NVPTR(pScrn);
733 NVPortPrivPtr pPriv = GET_BLIT_PRIVATE(pNv);
737 CARD32 dst_size, dst_point;
738 CARD32 src_point, src_format;
740 ScreenPtr pScreen = pScrn->pScreen;
741 PixmapPtr pPix = exaGetDrawablePixmap(pDraw);
744 /* Try to get the dest drawable into vram */
745 if (!exaPixmapIsOffscreen(pPix)) {
746 exaMoveInPixmap(pPix);
747 ExaOffscreenMarkUsed(pPix);
750 /* If we failed, draw directly onto the screen pixmap.
751 * Not sure if this is the best approach, maybe failing
752 * with BadAlloc would be better?
754 if (!exaPixmapIsOffscreen(pPix)) {
755 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
756 "XV: couldn't move dst surface into vram\n");
757 pPix = pScreen->GetScreenPixmap(pScreen);
760 NVAccelGetCtxSurf2DFormatFromPixmap(pPix, &dst_format);
761 NVAccelSetCtxSurf2D(pPix, pPix, dst_format);
764 /* Adjust coordinates if drawing to an offscreen pixmap */
765 if (pPix->screen_x || pPix->screen_y) {
766 REGION_TRANSLATE(pScrn->pScreen, clipBoxes,
769 dstBox->x1 -= pPix->screen_x;
770 dstBox->x2 -= pPix->screen_x;
771 dstBox->y1 -= pPix->screen_y;
772 dstBox->y2 -= pPix->screen_y;
775 DamageDamageRegion((DrawablePtr)pPix, clipBoxes);
778 pbox = REGION_RECTS(clipBoxes);
779 nbox = REGION_NUM_RECTS(clipBoxes);
781 dsdx = (src_w << 20) / drw_w;
782 dtdy = (src_h << 20) / drw_h;
784 dst_size = ((dstBox->y2 - dstBox->y1) << 16) |
785 (dstBox->x2 - dstBox->x1);
786 dst_point = (dstBox->y1 << 16) | dstBox->x1;
788 src_pitch |= (NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER |
789 NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_BILINEAR);
790 src_point = ((y1 << 4) & 0xffff0000) | (x1 >> 12);
795 NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8;
799 NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_YB8V8YA8U8;
803 NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_V8YB8U8YA8;
807 if(pPriv->SyncToVBlank) {
812 if(pNv->BlendingPossible) {
813 BEGIN_RING(NvScaledImage,
814 NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT, 2);
815 OUT_RING (src_format);
816 OUT_RING (NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
818 BEGIN_RING(NvScaledImage,
819 NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT, 2);
820 OUT_RING (src_format);
824 BEGIN_RING(NvRectangle,
825 NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1);
828 BEGIN_RING(NvScaledImage,
829 NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT, 6);
830 OUT_RING ((pbox->y1 << 16) | pbox->x1);
831 OUT_RING (((pbox->y2 - pbox->y1) << 16) |
832 (pbox->x2 - pbox->x1));
833 OUT_RING (dst_point);
838 BEGIN_RING(NvScaledImage,
839 NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4);
840 OUT_RING ((height << 16) | width);
841 OUT_RING (src_pitch);
842 OUT_RING (src_offset);
843 OUT_RING (src_point);
849 exaMarkSync(pScrn->pScreen);
851 pPriv->videoStatus = FREE_TIMER;
852 pPriv->videoTime = currentTime.milliseconds + FREE_DELAY;
853 pNv->VideoTimerCallback = NVVideoTimerCallback;
860 NVStopOverlayVideo(ScrnInfoPtr pScrn, pointer data, Bool Exit)
862 NVPtr pNv = NVPTR(pScrn);
863 NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
865 if(pPriv->grabbedByV4L) return;
867 REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
870 if (pPriv->videoStatus & CLIENT_VIDEO_ON)
871 NVStopOverlay(pScrn);
872 NVFreeOverlayMemory(pScrn);
873 pPriv->videoStatus = 0;
875 if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
876 pPriv->videoStatus = OFF_TIMER | CLIENT_VIDEO_ON;
877 pPriv->videoTime = currentTime.milliseconds + OFF_DELAY;
878 pNv->VideoTimerCallback = NVVideoTimerCallback;
887 NVStopBlitVideo(ScrnInfoPtr pScrn, pointer data, Bool Exit)
892 * NVSetOverlayPortAttribute
893 * sets the attribute "attribute" of port "data" to value "value"
894 * calls NVResetVideo(pScrn) to apply changes to hardware
897 * @param attribute attribute to set
898 * @param value value to which attribute is to be set
899 * @param data port from which the attribute is to be set
901 * @return Success, if setting is successful
902 * BadValue/BadMatch, if value/attribute are invalid
903 * @see NVResetVideo(ScrnInfoPtr pScrn)
906 NVSetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
907 INT32 value, pointer data)
909 NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
911 if (attribute == xvBrightness) {
912 if ((value < -512) || (value > 512))
914 pPriv->brightness = value;
916 if (attribute == xvDoubleBuffer) {
917 if ((value < 0) || (value > 1))
919 pPriv->doubleBuffer = value;
921 if (attribute == xvContrast) {
922 if ((value < 0) || (value > 8191))
924 pPriv->contrast = value;
926 if (attribute == xvHue) {
932 if (attribute == xvSaturation) {
933 if ((value < 0) || (value > 8191))
935 pPriv->saturation = value;
937 if (attribute == xvColorKey) {
938 pPriv->colorKey = value;
939 REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
941 if (attribute == xvAutopaintColorKey) {
942 if ((value < 0) || (value > 1))
944 pPriv->autopaintColorKey = value;
946 if (attribute == xvITURBT709) {
947 if ((value < 0) || (value > 1))
949 pPriv->iturbt_709 = value;
951 if (attribute == xvSetDefaults) {
952 NVSetPortDefaults(pScrn, pPriv);
961 * NVGetOverlayPortAttribute
963 * @param pScrn unused
964 * @param attribute attribute to be read
965 * @param value value of attribute will be stored in this pointer
966 * @param data port from which attribute will be read
967 * @return Success, if queried attribute exists
970 NVGetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
971 INT32 *value, pointer data)
973 NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
975 if (attribute == xvBrightness)
976 *value = pPriv->brightness;
977 else if (attribute == xvDoubleBuffer)
978 *value = (pPriv->doubleBuffer) ? 1 : 0;
979 else if (attribute == xvContrast)
980 *value = pPriv->contrast;
981 else if (attribute == xvSaturation)
982 *value = pPriv->saturation;
983 else if (attribute == xvHue)
985 else if (attribute == xvColorKey)
986 *value = pPriv->colorKey;
987 else if (attribute == xvAutopaintColorKey)
988 *value = (pPriv->autopaintColorKey) ? 1 : 0;
989 else if (attribute == xvITURBT709)
990 *value = (pPriv->iturbt_709) ? 1 : 0;
998 * NVSetBlitPortAttribute
999 * sets the attribute "attribute" of port "data" to value "value"
1000 * supported attributes:
1001 * - xvSyncToVBlank (values: 0,1)
1002 * - xvSetDefaults (values: NA; SyncToVBlank will be set, if hardware supports it)
1005 * @param attribute attribute to set
1006 * @param value value to which attribute is to be set
1007 * @param data port from which the attribute is to be set
1009 * @return Success, if setting is successful
1010 * BadValue/BadMatch, if value/attribute are invalid
1013 NVSetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
1014 INT32 value, pointer data)
1016 NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
1017 NVPtr pNv = NVPTR(pScrn);
1019 if ((attribute == xvSyncToVBlank) && pNv->WaitVSyncPossible) {
1020 if ((value < 0) || (value > 1))
1022 pPriv->SyncToVBlank = value;
1024 if (attribute == xvSetDefaults) {
1025 pPriv->SyncToVBlank = pNv->WaitVSyncPossible;
1033 * NVGetBlitPortAttribute
1034 * reads the value of attribute "attribute" from port "data" into INT32 "*value"
1035 * currently only one attribute supported: xvSyncToVBlank
1037 * @param pScrn unused
1038 * @param attribute attribute to be read
1039 * @param value value of attribute will be stored here
1040 * @param data port from which attribute will be read
1041 * @return Success, if queried attribute exists
1044 NVGetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
1045 INT32 *value, pointer data)
1047 NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
1049 if(attribute == xvSyncToVBlank)
1050 *value = (pPriv->SyncToVBlank) ? 1 : 0;
1060 * used by client applications to ask the driver:
1061 * how would you actually scale a video of dimensions
1062 * vid_w, vid_h, if i wanted you to scale it to dimensions
1064 * function stores actual scaling size in pointers p_w, p_h.
1067 * @param pScrn unused
1068 * @param motion unused
1069 * @param vid_w width of source video
1070 * @param vid_h height of source video
1071 * @param drw_w desired scaled width as requested by client
1072 * @param drw_h desired scaled height as requested by client
1073 * @param p_w actual scaled width as the driver is capable of
1074 * @param p_h actual scaled height as the driver is capable of
1075 * @param data unused
1078 NVQueryBestSize(ScrnInfoPtr pScrn, Bool motion,
1079 short vid_w, short vid_h,
1080 short drw_w, short drw_h,
1081 unsigned int *p_w, unsigned int *p_h,
1084 if(vid_w > (drw_w << 3))
1086 if(vid_h > (drw_h << 3))
1095 * used to convert YV12 to YUY2 for the blitter
1097 * @param src1 source buffer of luma
1098 * @param src2 source buffer of chroma1
1099 * @param src3 source buffer of chroma2
1100 * @param dst1 destination buffer
1101 * @param srcPitch pitch of src1
1102 * @param srcPitch2 pitch of src2, src3
1103 * @param dstPitch pitch of dst1
1104 * @param h number of lines to copy
1105 * @param w length of lines to copy
1107 static inline void NVCopyData420(unsigned char *src1, unsigned char *src2,
1108 unsigned char *src3, unsigned char *dst1,
1109 int srcPitch, int srcPitch2,
1114 CARD8 *s1, *s2, *s3;
1119 for (j = 0; j < h; j++) {
1120 dst = (CARD32*)dst1;
1121 s1 = src1; s2 = src2; s3 = src3;
1125 #if X_BYTE_ORDER == X_BIG_ENDIAN
1126 dst[0] = (s1[0] << 24) | (s1[1] << 8) | (s3[0] << 16) | s2[0];
1127 dst[1] = (s1[2] << 24) | (s1[3] << 8) | (s3[1] << 16) | s2[1];
1128 dst[2] = (s1[4] << 24) | (s1[5] << 8) | (s3[2] << 16) | s2[2];
1129 dst[3] = (s1[6] << 24) | (s1[7] << 8) | (s3[3] << 16) | s2[3];
1131 dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
1132 dst[1] = s1[2] | (s1[3] << 16) | (s3[1] << 8) | (s2[1] << 24);
1133 dst[2] = s1[4] | (s1[5] << 16) | (s3[2] << 8) | (s2[2] << 24);
1134 dst[3] = s1[6] | (s1[7] << 16) | (s3[3] << 8) | (s2[3] << 24);
1136 dst += 4; s2 += 4; s3 += 4; s1 += 8;
1141 #if X_BYTE_ORDER == X_BIG_ENDIAN
1142 dst[0] = (s1[0] << 24) | (s1[1] << 8) | (s3[0] << 16) | s2[0];
1144 dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
1160 * NVCopyNV12ColorPlanes
1161 * Used to convert YV12 color planes to NV12 (interleaved UV) for the overlay
1163 * @param src1 source buffer of chroma1
1164 * @param dst1 destination buffer
1165 * @param h number of lines to copy
1166 * @param w length of lines to copy
1167 * @param id source pixel format (YV12 or I420)
1169 static inline void NVCopyNV12ColorPlanes(unsigned char *src1, unsigned char * src2, unsigned char *dst, int dstPitch, int srcPitch2,
1179 for ( j = 0; j < h; j++ )
1181 unsigned char * us = src1;
1182 unsigned char * vs = src2;
1183 unsigned int * vuvud = (unsigned int *) dst;
1184 for ( i = 0; i < l; i++ )
1186 #if X_BYTE_ORDER == X_BIG_ENDIAN
1187 *vuvud++ = (vs[0]<<24) | (us[0]<<16) | (vs[1]<<8) | us[1];
1189 *vuvud++ = vs[0] | (us[0]<<8) | (vs[1]<<16) | (us[1]<<24);
1195 unsigned short *vud = (unsigned short *) vuvud;
1196 #if X_BYTE_ORDER == X_BIG_ENDIAN
1197 *vud = (vs[0]<<8) | (us[0] << 0);
1199 *vud = vs[0] | (us[0]<<8);
1210 static int NV_set_dimensions(ScrnInfoPtr pScrn, int action_flags, INT32 * xa, INT32 * xb, INT32 * ya, INT32 * yb,
1211 short * src_x, short * src_y, short * src_w, short * src_h,
1212 short * drw_x, short * drw_y, short * drw_w, short * drw_h,
1213 int * left, int * top, int * right, int * bottom,
1215 int * npixels, int * nlines,
1216 RegionPtr clipBoxes, short width, short height
1220 if ( action_flags & USE_OVERLAY )
1221 { /* overlay hardware scaler limitation - copied from nv, UNCHECKED*/
1222 if (*src_w > (*drw_w << 3))
1223 *drw_w = *src_w >> 3;
1224 if (*src_h > (*drw_h << 3))
1225 *drw_h = *src_h >> 3;
1231 *xb = *src_x + *src_w;
1233 *yb = *src_y + *src_h;
1235 dstBox->x1 = *drw_x;
1236 dstBox->x2 = *drw_x + *drw_w;
1237 dstBox->y1 = *drw_y;
1238 dstBox->y2 = *drw_y + *drw_h;
1240 if (!xf86XVClipVideoHelper(dstBox, xa, xb, ya, yb, clipBoxes,
1244 if ( action_flags & USE_OVERLAY )
1246 dstBox->x1 -= pScrn->frameX0;
1247 dstBox->x2 -= pScrn->frameX0;
1248 dstBox->y1 -= pScrn->frameY0;
1249 dstBox->y2 -= pScrn->frameY0;
1254 /* Convert fixed point to integer, as xf86XVClipVideoHelper probably turns its parameter into fixed point values */
1255 *left = (*xa) >> 16;
1256 if (*left < 0) *left = 0;
1258 if (*top < 0) *top = 0;
1259 *right = (*xb) >> 16;
1260 if (*right > width) *right = width;
1261 *bottom = (*yb) >> 16;
1262 if (*bottom > height) *bottom = height;
1264 if ( action_flags & IS_YV12 )
1266 *left &= ~1; //even "left", even "top", even number of pixels per line and even number of lines
1267 *npixels = ((*right + 1) & ~1) - *left;
1269 *nlines = ((*bottom + 1) & ~1) - *top;
1271 else if ( action_flags & IS_YUY2 )
1273 *left &= ~1; //even "left"
1274 *npixels = ((*right + 1) & ~1) - *left; //even number of pixels per line
1275 *nlines = *bottom - *top;
1276 *left <<= 1; //16bpp
1278 else if (action_flags & IS_RGB )
1280 *npixels = *right - *left;
1281 *nlines = *bottom - *top;
1282 *left <<= 2; //32bpp
1288 static int NV_calculate_pitches_and_mem_size(int action_flags, int * srcPitch, int * srcPitch2, int * dstPitch,
1289 int * s2offset, int * s3offset,
1290 int * newFBSize, int * newTTSize,
1291 int * line_len, int npixels, int nlines, int width, int height)
1295 if ( action_flags & IS_YV12 )
1297 *srcPitch = (width + 3) & ~3; /* of luma */
1298 *s2offset = *srcPitch * height;
1299 *srcPitch2 = ((width >> 1) + 3) & ~3; /*of chroma*/
1300 *s3offset = (*srcPitch2 * (height >> 1)) + *s2offset;
1301 *dstPitch = (npixels + 63) &~ 63; /*luma and chroma pitch*/
1302 *line_len = npixels;
1303 *newFBSize = nlines * *dstPitch + (nlines >> 1) * *dstPitch;
1304 *newTTSize = nlines * *dstPitch + (nlines >> 1) * *dstPitch;
1306 else if ( action_flags & IS_YUY2 )
1308 *srcPitch = width << 1; /* one luma, one chroma per pixel */
1309 *dstPitch = ((npixels << 1) + 63) & ~63;
1310 *line_len = npixels << 1;
1311 *newFBSize = nlines * *dstPitch;
1312 *newTTSize = nlines * *line_len;
1314 else if ( action_flags & IS_RGB )
1316 *srcPitch = width << 2; /* one R, one G, one B, one X per pixel */
1317 *dstPitch = ((npixels << 2) + 63) & ~63;
1318 *line_len = npixels << 2;
1319 *newFBSize = nlines * *dstPitch;
1320 *newTTSize = nlines * *dstPitch;
1324 if ( action_flags & CONVERT_TO_YUY2 )
1326 *dstPitch = ((npixels << 1) + 63) & ~63;
1327 *line_len = npixels << 1;
1328 *newFBSize = nlines * *dstPitch;
1329 *newTTSize = nlines * *line_len;
1332 if ( action_flags & SWAP_UV )
1333 { //I420 swaps U and V
1335 *s2offset = *s3offset;
1339 if ( action_flags & USE_OVERLAY ) // overlay double buffering ...
1340 (*newFBSize) <<= 1; // ... means double the amount of VRAM needed
1347 * NV_set_action_flags
1348 * This function computes the action flags from the input image,
1349 * that is, it decides what NVPutImage and its helpers must do.
1350 * This eases readability by avoiding lots of switch-case statements in the core NVPutImage
1352 static void NV_set_action_flags(NVPtr pNv, ScrnInfoPtr pScrn, DrawablePtr pDraw, NVPortPrivPtr pPriv, int id, int * action_flags)
1355 if ( id == FOURCC_YUY2 || id == FOURCC_UYVY )
1356 *action_flags |= IS_YUY2;
1358 if ( id == FOURCC_YV12 || id == FOURCC_I420 )
1359 *action_flags |= IS_YV12;
1361 if ( id == FOURCC_RGB ) /*How long will we support it?*/
1362 *action_flags |= IS_RGB;
1364 if ( id == FOURCC_I420 ) /*I420 is YV12 with swapped UV*/
1365 *action_flags |= SWAP_UV;
1367 if ( !pPriv -> blitter )
1368 *action_flags |= USE_OVERLAY;
1371 WindowPtr pWin = NULL;
1373 if (!noCompositeExtension && WindowDrawable(pDraw->type))
1375 pWin = (WindowPtr)pDraw;
1379 if ( pWin->redirectDraw )
1380 *action_flags &= ~USE_OVERLAY;
1384 if ( ! ( *action_flags & USE_OVERLAY) )
1386 if ( id == FOURCC_YV12 || id == FOURCC_I420 )
1387 { /*The blitter does not handle YV12 natively*/
1388 *action_flags |= CONVERT_TO_YUY2;
1392 if ( pNv->Architecture == NV_ARCH_04 )
1393 if ( * action_flags & IS_YV12 ) //NV04-05 don't support native YV12, only YUY2 and ITU-R BT.601)
1394 *action_flags |= CONVERT_TO_YUY2;
1396 if ( pNv->Architecture == NV_ARCH_10 || pNv->Architecture == NV_ARCH_20 )
1398 switch ( pNv->Chipset & 0xfff0 )
1403 case CHIPSET_NFORCE: /*XXX: unsure about nforce and nforce2*/
1404 case CHIPSET_NFORCE2:
1405 case CHIPSET_NV20: /*reported by pq - in fact all cards older than geforce4 ti probably don't have YV12 overlay*/
1406 *action_flags |= CONVERT_TO_YUY2; break;
1417 * PutImage is "the" important function of the Xv extension.
1418 * a client (e.g. video player) calls this function for every
1419 * image (of the video) to be displayed. this function then
1420 * scales and displays the image.
1422 * @param pScrn screen which hold the port where the image is put
1423 * @param src_x source point in the source image to start displaying from
1424 * @param src_y see above
1425 * @param src_w width of the source image to display
1426 * @param src_h see above
1427 * @param drw_x screen point to display to
1429 * @param drw_w width of the screen drawable
1431 * @param id pixel format of image
1432 * @param buf pointer to buffer containing the source image
1433 * @param width total width of the source image we are passed
1435 * @param Sync unused
1436 * @param clipBoxes ??
1437 * @param data pointer to port
1438 * @param pDraw drawable pointer
1441 NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
1442 short drw_x, short drw_y,
1443 short src_w, short src_h,
1444 short drw_w, short drw_h,
1447 short width, short height,
1448 Bool Sync, /*FIXME: need to honor the Sync*/
1449 RegionPtr clipBoxes,
1454 NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
1455 NVPtr pNv = NVPTR(pScrn);
1456 INT32 xa = 0, xb = 0, ya = 0, yb = 0; //source box
1457 int newFBSize = 0, newTTSize = 0; //size to allocate in VRAM and in GART respectively
1458 int offset = 0, s2offset = 0, s3offset = 0; //card VRAM offset, source offsets for U and V planes
1459 int srcPitch = 0, srcPitch2 = 0, dstPitch = 0; //source pitch, source pitch of U and V planes in case of YV12, VRAM destination pitch
1460 int top = 0, left = 0, right = 0, bottom = 0, npixels = 0, nlines = 0; //position of the given source data (using src_*), number of pixels and lines we are interested in
1464 int line_len = 0; //length of a line, like npixels, but in bytes
1465 int DMAoffset = 0; //additional VRAM offset to start the DMA copy to
1466 int UVDMAoffset = 0;
1467 NVAllocRec * destination_buffer = NULL;
1468 unsigned char * video_mem_destination = NULL;
1469 int action_flags; //what shall we do?
1472 if (pPriv->grabbedByV4L)
1476 NV_set_action_flags(pNv, pScrn, pDraw, pPriv, id, &action_flags);
1478 if ( NV_set_dimensions(pScrn, action_flags, &xa, &xb, &ya, &yb,
1479 &src_x, &src_y, &src_w, &src_h,
1480 &drw_x, &drw_y, &drw_w, &drw_h,
1481 &left, &top, &right, &bottom, &dstBox,
1483 clipBoxes, width, height ) )
1489 if ( NV_calculate_pitches_and_mem_size(action_flags, &srcPitch, &srcPitch2, &dstPitch,
1490 &s2offset, &s3offset,
1491 & newFBSize, &newTTSize ,&line_len ,
1492 npixels, nlines, width, height) )
1494 return BadImplementation;
1497 /* There are some cases (tvtime with overscan for example) where the input image is larger (width/height) than
1498 the source rectangle for the overlay (src_w, src_h). In those cases, we try to do something optimal by uploading only
1499 the necessary data. */
1500 if ( action_flags & IS_YUY2 || action_flags & IS_RGB )
1502 buf += (top * srcPitch) + left;
1503 DMAoffset += left + (top * dstPitch);
1506 if ( action_flags & IS_YV12 )
1508 tmp = ((top >> 1) * srcPitch2) + (left >> 1);
1512 if ( action_flags & CONVERT_TO_YUY2 )
1514 DMAoffset += (left << 1) + (top * dstPitch);
1519 //real YV12 - we offset only the luma plane, and copy the whole color plane, for easiness
1520 DMAoffset += left + (top * dstPitch);
1521 UVDMAoffset += left + (top >> 1) * dstPitch;
1525 pPriv->video_mem = NVAllocateVideoMemory(pScrn, pPriv->video_mem,
1527 if (!pPriv->video_mem)
1530 offset = pPriv->video_mem->offset;
1532 /*The overlay supports hardware double buffering. We handle this here*/
1533 if (pPriv->doubleBuffer) {
1534 int mask = 1 << (pPriv->currentBuffer << 2);
1535 /* overwrite the newest buffer if there's not one free */
1536 if (nvReadVIDEO(pNv, NV_PVIDEO_BUFFER) & mask) {
1537 if (!pPriv->currentBuffer)
1538 offset += newFBSize >> 1;
1542 if (pPriv->currentBuffer)
1543 offset += newFBSize >> 1;
1546 /*Now we take a decision regarding the way we send the data to the card.
1547 Either we use double buffering of "private" TT memory
1548 Either we rely on X's GARTScratch
1549 Either we fallback on CPU copy
1552 /* Try to allocate host-side double buffers, unless we have already failed*/
1553 /* We take only nlines * line_len bytes - that is, only the pixel data we are interested in - because the stuff in the GART is
1554 written contiguously */
1555 if ( pPriv -> currentHostBuffer != NO_PRIV_HOST_BUFFER_AVAILABLE )
1557 pPriv->TT_mem_chunk[0] = NVAllocateTTMemory(pScrn, pPriv->TT_mem_chunk[0],
1559 if ( pPriv->TT_mem_chunk[0] )
1561 pPriv->TT_mem_chunk[1] = NVAllocateTTMemory(pScrn, pPriv->TT_mem_chunk[1],
1564 if ( ! pPriv->TT_mem_chunk[1] )
1566 NVFreeMemory(pNv, pPriv->TT_mem_chunk[0]);
1567 pPriv->TT_mem_chunk[0] = NULL;
1568 pPriv -> currentHostBuffer = NO_PRIV_HOST_BUFFER_AVAILABLE;
1569 //xf86DrvMsg(0, X_INFO, "Alloc 1 failed\n");
1574 pPriv -> currentHostBuffer = NO_PRIV_HOST_BUFFER_AVAILABLE;
1575 //xf86DrvMsg(0, X_INFO, "Alloc 0 failed\n");
1579 if ( pPriv->currentHostBuffer != NO_PRIV_HOST_BUFFER_AVAILABLE )
1580 { //if we have a private buffer
1581 destination_buffer = pPriv->TT_mem_chunk[pPriv->currentHostBuffer];
1582 //xf86DrvMsg(0, X_INFO, "Using private mem chunk #%d\n", pPriv->currentHostBuffer);
1584 /* We know where we are going to write, but we are not sure yet whether we can do it directly, because
1585 the card could be working on the buffer for the last-but-one frame. So we check if we have a notifier ready or not.
1586 If we do, then we must wait for it before overwriting the buffer.
1587 Else we need one, so we call the Xv notifier allocator.*/
1588 if ( pPriv->DMANotifier [ pPriv->currentHostBuffer ] )
1590 //xf86DrvMsg(0, X_INFO, "Waiting for notifier %p (%d)\n", pPriv->DMANotifier[pPriv->currentHostBuffer], pPriv->currentHostBuffer);
1591 if (!NVNotifierWaitStatus(pScrn, pPriv->DMANotifier[pPriv->currentHostBuffer], 0, 0))
1596 //xf86DrvMsg(0, X_INFO, "Allocating notifier...\n");
1597 pPriv->DMANotifier [ pPriv->currentHostBuffer ] = NVXvDMANotifierAlloc(pScrn);
1598 if (! pPriv->DMANotifier [ pPriv->currentHostBuffer ] )
1599 { /* In case we are out of notifiers (then our guy is watching 3 movies at a time!!), we fallback on global GART, and free the private buffers.
1600 I know that's a lot of code but I believe it's necessary to properly handle all the cases*/
1601 xf86DrvMsg(0, X_ERROR, "Ran out of Xv notifiers!\n");
1602 NVFreeMemory(pNv, pPriv->TT_mem_chunk[0]);
1603 pPriv->TT_mem_chunk[0] = NULL;
1604 NVFreeMemory(pNv, pPriv->TT_mem_chunk[1]);
1605 pPriv->TT_mem_chunk[1] = NULL;
1606 pPriv -> currentHostBuffer = NO_PRIV_HOST_BUFFER_AVAILABLE;
1608 //xf86DrvMsg(0, X_INFO, "Got notifier %p\n", pPriv->DMANotifier [ pPriv->currentHostBuffer ]);
1612 if ( pPriv -> currentHostBuffer == NO_PRIV_HOST_BUFFER_AVAILABLE )
1613 { //otherwise we fall back on DDX's GARTScratch
1614 destination_buffer = pNv->GARTScratch;
1615 //xf86DrvMsg(0, X_INFO, "Using global GART memory chunk\n");
1618 if ( !destination_buffer) //if we have no GART at all
1621 if(newTTSize <= destination_buffer->size)
1623 unsigned char *dst = destination_buffer->map;
1626 /* Upload to GART */
1627 if ( action_flags & IS_YV12)
1629 if ( action_flags & CONVERT_TO_YUY2 )
1631 NVCopyData420(buf + (top * srcPitch) + left,
1632 buf + s2offset, buf + s3offset,
1633 dst, srcPitch, srcPitch2,
1634 line_len, nlines, npixels);
1638 unsigned char * tbuf = buf + top * srcPitch + left;
1639 unsigned char * tdst = dst;
1640 //xf86DrvMsg(0, X_INFO, "srcPitch %d dstPitch %d srcPitch2 %d nlines %d npixels %d left %d top %d s2offset %d\n", srcPitch, dstPitch, srcPitch2, nlines, npixels, left, top, s2offset);
1642 for ( i=0; i < nlines; i++)
1644 memcpy(tdst, tbuf, line_len);
1648 dst += line_len * nlines;
1649 NVCopyNV12ColorPlanes(buf + s2offset, buf + s3offset, dst, line_len, srcPitch2, nlines, line_len);
1654 for ( i=0; i < nlines; i++)
1656 memcpy(dst, buf, line_len);
1663 BEGIN_RING(NvMemFormat,
1664 NV_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2);
1667 pNv->M2MFDirection = 1;
1670 if ( action_flags & IS_YV12 && ! (action_flags & CONVERT_TO_YUY2) )
1671 { /*we start the color plane transfer separately*/
1672 BEGIN_RING(NvMemFormat,
1673 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
1674 OUT_RING ((uint32_t)destination_buffer->offset + line_len * nlines);
1675 OUT_RING ((uint32_t)offset + dstPitch * nlines);
1676 OUT_RING (line_len);
1677 OUT_RING (dstPitch);
1678 OUT_RING (line_len);
1679 OUT_RING ((nlines >> 1));
1680 OUT_RING ((1<<8)|1);
1685 BEGIN_RING(NvMemFormat,
1686 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
1687 OUT_RING ((uint32_t)destination_buffer->offset);
1688 OUT_RING ((uint32_t)offset /*+ DMAoffset*/);
1689 OUT_RING (line_len);
1690 OUT_RING (dstPitch);
1691 OUT_RING (line_len);
1693 OUT_RING ((1<<8)|1);
1696 if ( destination_buffer == pNv->GARTScratch )
1698 NVNotifierReset(pScrn, pNv->Notifier0);
1701 NVNotifierReset(pScrn, pPriv->DMANotifier[pPriv->currentHostBuffer]);
1702 BEGIN_RING(NvMemFormat,
1703 NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
1704 OUT_RING (pPriv->DMANotifier[pPriv->currentHostBuffer]->handle);
1708 BEGIN_RING(NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
1711 BEGIN_RING(NvMemFormat, 0x100, 1);
1714 //Put back NvDmaNotifier0 for EXA
1715 BEGIN_RING(NvMemFormat,
1716 NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
1717 OUT_RING (NvDmaNotifier0);
1721 if ( destination_buffer == pNv->GARTScratch )
1722 if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0))
1725 else { //GART is too small, we fallback on CPU copy
1727 video_mem_destination = pPriv->video_mem->map + (offset - (uint32_t)pPriv->video_mem->offset);
1729 if ( action_flags & IS_YV12 )
1731 if ( action_flags & CONVERT_TO_YUY2 )
1733 NVCopyData420(buf + (top * srcPitch) + left,
1734 buf + s2offset, buf + s3offset,
1735 video_mem_destination, srcPitch, srcPitch2,
1736 dstPitch, nlines, npixels);
1739 unsigned char * tbuf = buf + left + top * srcPitch;
1740 for ( i=0; i < nlines; i++)
1742 int dwords = npixels << 1;
1743 while (dwords & ~0x03)
1745 *video_mem_destination = *tbuf;
1746 *(video_mem_destination + 1) = *(tbuf + 1);
1747 *(video_mem_destination + 2) = *(tbuf + 2);
1748 *(video_mem_destination + 3) = *(tbuf + 3);
1749 video_mem_destination += 4;
1756 *(video_mem_destination + 2) = *(tbuf + 2);
1758 *(video_mem_destination + 1) = *(tbuf + 1);
1760 *video_mem_destination = *tbuf;
1763 video_mem_destination += dstPitch - (npixels << 1);
1764 tbuf += srcPitch - (npixels << 1);
1767 NVCopyNV12ColorPlanes(buf + s2offset, buf + s3offset, video_mem_destination, dstPitch, srcPitch2, nlines, line_len);
1772 for ( i=0; i < nlines; i++)
1774 int dwords = npixels << 1;
1775 while (dwords & ~0x03)
1777 *video_mem_destination = *buf;
1778 *(video_mem_destination + 1) = *(buf + 1);
1779 *(video_mem_destination + 2) = *(buf + 2);
1780 *(video_mem_destination + 3) = *(buf + 3);
1781 video_mem_destination += 4;
1788 *(video_mem_destination + 2) = *(buf + 2);
1790 *(video_mem_destination + 1) = *(buf + 1);
1792 *video_mem_destination = *buf;
1795 video_mem_destination += dstPitch - (npixels << 1);
1796 buf += srcPitch - (npixels << 1);
1804 if ( pPriv->currentHostBuffer != NO_PRIV_HOST_BUFFER_AVAILABLE )
1805 pPriv->currentHostBuffer ^= 1;
1807 if ( action_flags & USE_OVERLAY )
1809 if ( pNv->Architecture == NV_ARCH_04 )
1810 NV04PutOverlayImage(pScrn, offset, id,
1814 src_w, src_h, drw_w, drw_h,
1817 NVPutOverlayImage(pScrn, offset, ((action_flags & IS_YUY2) || (action_flags & CONVERT_TO_YUY2)) ? 0 : offset + nlines * dstPitch, id,
1821 src_w, src_h, drw_w, drw_h,
1823 pPriv->currentBuffer ^= 1;
1828 NVPutBlitImage(pScrn, offset, id,
1832 src_w, src_h, drw_w, drw_h,
1840 * QueryImageAttributes
1843 * - size (memory required to store image),
1847 * depending on colorspace (id) and dimensions (w,h) of image
1851 * may be adjusted as needed
1853 * @param pScrn unused
1854 * @param id colorspace of image
1855 * @param w pointer to width of image
1856 * @param h pointer to height of image
1857 * @param pitches pitches[i] = length of a scanline in plane[i]
1858 * @param offsets offsets[i] = offset of plane i from the beginning of the image
1859 * @return size of the memory required for the XvImage queried
1862 NVQueryImageAttributes(ScrnInfoPtr pScrn, int id,
1863 unsigned short *w, unsigned short *h,
1864 int *pitches, int *offsets)
1868 if (*w > IMAGE_MAX_W)
1870 if (*h > IMAGE_MAX_H)
1873 *w = (*w + 1) & ~1; // width rounded up to an even number
1880 *h = (*h + 1) & ~1; // height rounded up to an even number
1881 size = (*w + 3) & ~3; // width rounded up to a multiple of 4
1883 pitches[0] = size; // width rounded up to a multiple of 4
1886 offsets[1] = size; // number of pixels in "rounded up" image
1887 tmp = ((*w >> 1) + 3) & ~3; // width/2 rounded up to a multiple of 4
1889 pitches[1] = pitches[2] = tmp; // width/2 rounded up to a multiple of 4
1890 tmp *= (*h >> 1); // 1/4*number of pixels in "rounded up" image
1891 size += tmp; // 5/4*number of pixels in "rounded up" image
1893 offsets[2] = size; // 5/4*number of pixels in "rounded up" image
1894 size += tmp; // = 3/2*number of pixels in "rounded up" image
1898 size = *w << 1; // 2*width
1900 pitches[0] = size; // 2*width
1901 size *= *h; // 2*width*height
1904 size = *w << 2; // 4*width (32 bit per pixel)
1906 pitches[0] = size; // 4*width
1907 size *= *h; // 4*width*height
1917 /***** Exported offscreen surface stuff ****/
1921 NVAllocSurface(ScrnInfoPtr pScrn, int id,
1922 unsigned short w, unsigned short h,
1923 XF86SurfacePtr surface)
1925 NVPtr pNv = NVPTR(pScrn);
1926 NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
1929 bpp = pScrn->bitsPerPixel >> 3;
1931 if (pPriv->grabbedByV4L)
1934 if ((w > IMAGE_MAX_W) || (h > IMAGE_MAX_H))
1938 pPriv->pitch = ((w << 1) + 63) & ~63;
1939 size = h * pPriv->pitch / bpp;
1941 pPriv->video_mem = NVAllocateVideoMemory(pScrn,
1944 if (!pPriv->video_mem)
1950 surface->height = h;
1951 surface->pScrn = pScrn;
1952 surface->pitches = &pPriv->pitch;
1953 surface->offsets = &pPriv->offset;
1954 surface->devPrivate.ptr = (pointer)pPriv;
1957 /* grab the video */
1958 NVStopOverlay(pScrn);
1959 pPriv->videoStatus = 0;
1960 REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
1961 pPriv->grabbedByV4L = TRUE;
1967 NVStopSurface(XF86SurfacePtr surface)
1969 NVPortPrivPtr pPriv = (NVPortPrivPtr)(surface->devPrivate.ptr);
1971 if (pPriv->grabbedByV4L && pPriv->videoStatus) {
1972 NVStopOverlay(surface->pScrn);
1973 pPriv->videoStatus = 0;
1980 NVFreeSurface(XF86SurfacePtr surface)
1982 NVPortPrivPtr pPriv = (NVPortPrivPtr)(surface->devPrivate.ptr);
1984 if (pPriv->grabbedByV4L) {
1985 NVStopSurface(surface);
1986 NVFreeOverlayMemory(surface->pScrn);
1987 pPriv->grabbedByV4L = FALSE;
1994 NVGetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value)
1996 NVPtr pNv = NVPTR(pScrn);
1997 NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
1999 return NVGetOverlayPortAttribute(pScrn, attribute,
2000 value, (pointer)pPriv);
2004 NVSetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value)
2006 NVPtr pNv = NVPTR(pScrn);
2007 NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
2009 return NVSetOverlayPortAttribute(pScrn, attribute,
2010 value, (pointer)pPriv);
2014 NVDisplaySurface(XF86SurfacePtr surface,
2015 short src_x, short src_y,
2016 short drw_x, short drw_y,
2017 short src_w, short src_h,
2018 short drw_w, short drw_h,
2019 RegionPtr clipBoxes)
2021 ScrnInfoPtr pScrn = surface->pScrn;
2022 NVPortPrivPtr pPriv = (NVPortPrivPtr)(surface->devPrivate.ptr);
2023 INT32 xa, xb, ya, yb;
2026 if (!pPriv->grabbedByV4L)
2029 if (src_w > (drw_w << 3))
2031 if (src_h > (drw_h << 3))
2041 dstBox.x2 = drw_x + drw_w;
2043 dstBox.y2 = drw_y + drw_h;
2045 if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes,
2046 surface->width, surface->height))
2049 dstBox.x1 -= pScrn->frameX0;
2050 dstBox.x2 -= pScrn->frameX0;
2051 dstBox.y1 -= pScrn->frameY0;
2052 dstBox.y2 -= pScrn->frameY0;
2054 pPriv->currentBuffer = 0;
2056 NVPutOverlayImage(pScrn, surface->offsets[0], 0, surface->id,
2057 surface->pitches[0], &dstBox, xa, ya, xb, yb,
2058 surface->width, surface->height, src_w, src_h,
2059 drw_w, drw_h, clipBoxes);
2066 * this function does all the work setting up a blit port
2070 static XF86VideoAdaptorPtr
2071 NVSetupBlitVideo (ScreenPtr pScreen)
2073 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2074 NVPtr pNv = NVPTR(pScrn);
2075 XF86VideoAdaptorPtr adapt;
2076 NVPortPrivPtr pPriv;
2079 if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
2080 sizeof(NVPortPrivRec) +
2081 (sizeof(DevUnion) * NUM_BLIT_PORTS)))) {
2085 adapt->type = XvWindowMask | XvInputMask | XvImageMask;
2087 adapt->name = "NV Video Blitter";
2088 adapt->nEncodings = 1;
2089 adapt->pEncodings = &DummyEncoding;
2090 adapt->nFormats = NUM_FORMATS_ALL;
2091 adapt->pFormats = NVFormats;
2092 adapt->nPorts = NUM_BLIT_PORTS;
2093 adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
2095 pPriv = (NVPortPrivPtr)(&adapt->pPortPrivates[NUM_BLIT_PORTS]);
2096 for(i = 0; i < NUM_BLIT_PORTS; i++)
2097 adapt->pPortPrivates[i].ptr = (pointer)(pPriv);
2099 if(pNv->WaitVSyncPossible) {
2100 adapt->pAttributes = NVBlitAttributes;
2101 adapt->nAttributes = NUM_BLIT_ATTRIBUTES;
2103 adapt->pAttributes = NULL;
2104 adapt->nAttributes = 0;
2107 adapt->pImages = NVImages;
2108 adapt->nImages = NUM_IMAGES_ALL;
2109 adapt->PutVideo = NULL;
2110 adapt->PutStill = NULL;
2111 adapt->GetVideo = NULL;
2112 adapt->GetStill = NULL;
2113 adapt->StopVideo = NVStopBlitVideo;
2114 adapt->SetPortAttribute = NVSetBlitPortAttribute;
2115 adapt->GetPortAttribute = NVGetBlitPortAttribute;
2116 adapt->QueryBestSize = NVQueryBestSize;
2117 adapt->PutImage = NVPutImage;
2118 adapt->QueryImageAttributes = NVQueryImageAttributes;
2120 pPriv->videoStatus = 0;
2121 pPriv->grabbedByV4L = FALSE;
2122 pPriv->blitter = TRUE;
2123 pPriv->doubleBuffer = FALSE;
2124 pPriv->SyncToVBlank = pNv->WaitVSyncPossible;
2126 pNv->blitAdaptor = adapt;
2127 xvSyncToVBlank = MAKE_ATOM("XV_SYNC_TO_VBLANK");
2133 * NVSetupOverlayVideo
2134 * this function does all the work setting up an overlay port
2136 * @return overlay port
2137 * @see NVResetVideo(ScrnInfoPtr pScrn)
2139 static XF86VideoAdaptorPtr
2140 NVSetupOverlayVideoAdapter(ScreenPtr pScreen)
2142 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2143 NVPtr pNv = NVPTR(pScrn);
2144 XF86VideoAdaptorPtr adapt;
2145 NVPortPrivPtr pPriv;
2147 if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
2148 sizeof(NVPortPrivRec) +
2149 sizeof(DevUnion)))) {
2153 adapt->type = XvWindowMask | XvInputMask | XvImageMask;
2154 adapt->flags = VIDEO_OVERLAID_IMAGES|VIDEO_CLIP_TO_VIEWPORT;
2155 adapt->name = "NV Video Overlay";
2156 adapt->nEncodings = 1;
2157 adapt->pEncodings = &DummyEncoding;
2158 adapt->nFormats = NUM_FORMATS_ALL;
2159 adapt->pFormats = NVFormats;
2161 adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
2163 pPriv = (NVPortPrivPtr)(&adapt->pPortPrivates[1]);
2164 adapt->pPortPrivates[0].ptr = (pointer)(pPriv);
2166 adapt->pAttributes = (pNv->Architecture != NV_ARCH_04) ? NVOverlayAttributes : NV04OverlayAttributes;
2167 adapt->nAttributes = (pNv->Architecture != NV_ARCH_04) ? NUM_OVERLAY_ATTRIBUTES : NUM_NV04_OVERLAY_ATTRIBUTES;
2168 adapt->pImages = NVImages;
2169 adapt->nImages = NUM_IMAGES_YUV;
2170 adapt->PutVideo = NULL;
2171 adapt->PutStill = NULL;
2172 adapt->GetVideo = NULL;
2173 adapt->GetStill = NULL;
2174 adapt->StopVideo = NVStopOverlayVideo;
2175 adapt->SetPortAttribute = NVSetOverlayPortAttribute;
2176 adapt->GetPortAttribute = NVGetOverlayPortAttribute;
2177 adapt->QueryBestSize = NVQueryBestSize;
2178 adapt->PutImage = NVPutImage;
2179 adapt->QueryImageAttributes = NVQueryImageAttributes;
2181 pPriv->videoStatus = 0;
2182 pPriv->currentBuffer = 0;
2183 pPriv->grabbedByV4L = FALSE;
2184 pPriv->blitter = FALSE;
2185 if ( pNv->Architecture == NV_ARCH_04 )
2186 pPriv->doubleBuffer = 0;
2188 NVSetPortDefaults (pScrn, pPriv);
2190 /* gotta uninit this someplace */
2191 REGION_NULL(pScreen, &pPriv->clip);
2193 pNv->overlayAdaptor = adapt;
2195 xvColorKey = MAKE_ATOM("XV_COLORKEY");
2196 if ( pNv->Architecture != NV_ARCH_04 )
2198 xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
2199 xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
2200 xvContrast = MAKE_ATOM("XV_CONTRAST");
2201 xvSaturation = MAKE_ATOM("XV_SATURATION");
2202 xvHue = MAKE_ATOM("XV_HUE");
2203 xvAutopaintColorKey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
2204 xvSetDefaults = MAKE_ATOM("XV_SET_DEFAULTS");
2205 xvITURBT709 = MAKE_ATOM("XV_ITURBT_709");
2208 NVResetVideo(pScrn);
2214 XF86OffscreenImageRec NVOffscreenImages[2] = {
2217 VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
2222 NVGetSurfaceAttribute,
2223 NVSetSurfaceAttribute,
2224 IMAGE_MAX_W, IMAGE_MAX_H,
2225 NUM_OVERLAY_ATTRIBUTES - 1,
2226 &NVOverlayAttributes[1]
2230 VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
2235 NVGetSurfaceAttribute,
2236 NVSetSurfaceAttribute,
2237 IMAGE_MAX_W, IMAGE_MAX_H,
2238 NUM_OVERLAY_ATTRIBUTES - 1,
2239 &NVOverlayAttributes[1]
2244 NVInitOffscreenImages (ScreenPtr pScreen)
2246 xf86XVRegisterOffscreenImages(pScreen, NVOffscreenImages, 2);
2250 * NVChipsetHasOverlay
2252 * newer chips don't support overlay anymore.
2253 * overlay feature is emulated via textures.
2256 * @return true, if chipset supports overlay
2259 NVChipsetHasOverlay(NVPtr pNv)
2261 switch (pNv->Architecture) {
2262 case NV_ARCH_04: /*NV04 has a different overlay than NV10+*/
2268 if ((pNv->Chipset & 0xfff0) == CHIPSET_NV40)
2279 * NVSetupOverlayVideo
2280 * check if chipset supports Overlay and CompositeExtension is disabled.
2281 * if so, setup overlay port
2283 * @return overlay port
2284 * @see NVChipsetHasOverlay(NVPtr pNv)
2285 * @see NV10SetupOverlayVideo(ScreenPtr pScreen)
2286 * @see NVInitOffscreenImages(ScreenPtr pScreen)
2288 static XF86VideoAdaptorPtr
2289 NVSetupOverlayVideo(ScreenPtr pScreen)
2291 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2292 XF86VideoAdaptorPtr overlayAdaptor = NULL;
2293 NVPtr pNv = NVPTR(pScrn);
2295 if (!NVChipsetHasOverlay(pNv))
2298 overlayAdaptor = NVSetupOverlayVideoAdapter(pScreen);
2299 if (overlayAdaptor && pNv->Architecture != NV_ARCH_04 )
2300 NVInitOffscreenImages(pScreen); //I am not sure what this call does.
2303 if (!noCompositeExtension) {
2304 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2305 "XV: Composite is enabled, enabling overlay with smart blitter fallback\n");
2306 overlayAdaptor -> name = "NV Video Overlay with Composite";
2310 return overlayAdaptor;
2315 * tries to initialize one new overlay port and one new blit port
2316 * and add them to the list of ports on screen "pScreen".
2319 * @see NVSetupOverlayVideo(ScreenPtr pScreen)
2320 * @see NVSetupBlitVideo(ScreenPtr pScreen)
2322 void NVInitVideo (ScreenPtr pScreen)
2324 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2325 NVPtr pNv = NVPTR(pScrn);
2326 XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
2327 XF86VideoAdaptorPtr overlayAdaptor = NULL;
2328 XF86VideoAdaptorPtr blitAdaptor = NULL;
2332 * Driving the blitter requires the DMA FIFO. Using the FIFO
2333 * without accel causes DMA errors. While the overlay might
2334 * might work without accel, we also disable it for now when
2335 * acceleration is disabled:
2337 if (pScrn->bitsPerPixel != 8 && pNv->Architecture < NV_ARCH_50 && !pNv->NoAccel) {
2338 overlayAdaptor = NVSetupOverlayVideo(pScreen);
2339 blitAdaptor = NVSetupBlitVideo(pScreen);
2342 num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
2343 if(blitAdaptor || overlayAdaptor) {
2344 int size = num_adaptors;
2346 if(overlayAdaptor) size++;
2347 if(blitAdaptor) size++;
2349 newAdaptors = xalloc(size * sizeof(XF86VideoAdaptorPtr *));
2352 memcpy(newAdaptors, adaptors, num_adaptors *
2353 sizeof(XF86VideoAdaptorPtr));
2356 if(overlayAdaptor) {
2357 newAdaptors[num_adaptors] = overlayAdaptor;
2362 newAdaptors[num_adaptors] = blitAdaptor;
2366 adaptors = newAdaptors;
2371 xf86XVScreenInit(pScreen, adaptors, num_adaptors);