1fda9279dSmrg/* 2fda9279dSmrg * Copyright 2007 Arthur Huillet 3fda9279dSmrg * 4fda9279dSmrg * Permission is hereby granted, free of charge, to any person obtaining a 5fda9279dSmrg * copy of this software and associated documentation files (the "Software"), 6fda9279dSmrg * to deal in the Software without restriction, including without limitation 7fda9279dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8fda9279dSmrg * and/or sell copies of the Software, and to permit persons to whom the 9fda9279dSmrg * Software is furnished to do so, subject to the following conditions: 10fda9279dSmrg * 11fda9279dSmrg * The above copyright notice and this permission notice shall be included in 12fda9279dSmrg * all copies or substantial portions of the Software. 13fda9279dSmrg * 14fda9279dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15fda9279dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16fda9279dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17fda9279dSmrg * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18fda9279dSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19fda9279dSmrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20fda9279dSmrg * SOFTWARE. 21fda9279dSmrg */ 22fda9279dSmrg 23fda9279dSmrg#ifdef HAVE_CONFIG_H 24fda9279dSmrg#include "config.h" 25fda9279dSmrg#endif 26fda9279dSmrg 27479f40c1Smrg#include "xorg-config.h" 28fda9279dSmrg#include "xf86xv.h" 29fda9279dSmrg#include <X11/extensions/Xv.h> 30fda9279dSmrg#include "exa.h" 31fda9279dSmrg#include "damage.h" 32fda9279dSmrg#include "dixstruct.h" 33fda9279dSmrg#include "fourcc.h" 34fda9279dSmrg 35fda9279dSmrg#include "nv_include.h" 36fda9279dSmrg#include "nv_dma.h" 37fda9279dSmrg 38fda9279dSmrg#include "hwdefs/nv_object.xml.h" 39fda9279dSmrg#include "hwdefs/nv01_2d.xml.h" 40fda9279dSmrg#include "nv04_accel.h" 41fda9279dSmrg 42fda9279dSmrg#define FOURCC_RGB 0x0000003 43fda9279dSmrg 44fda9279dSmrg#define VSYNC_POSSIBLE (pNv->dev->chipset >= 0x11) 45fda9279dSmrg 46fda9279dSmrgextern Atom xvSetDefaults, xvSyncToVBlank; 47fda9279dSmrg 48fda9279dSmrgBool 49fda9279dSmrgNVPutBlitImage(ScrnInfoPtr pScrn, struct nouveau_bo *src, int src_offset, 50fda9279dSmrg int id, int src_pitch, BoxPtr dstBox, 51fda9279dSmrg int x1, int y1, int x2, int y2, 52fda9279dSmrg short width, short height, 53fda9279dSmrg short src_w, short src_h, 54fda9279dSmrg short drw_w, short drw_h, 55fda9279dSmrg RegionPtr clipBoxes, PixmapPtr ppix) 56fda9279dSmrg{ 57fda9279dSmrg NVPtr pNv = NVPTR(pScrn); 58fda9279dSmrg NVPortPrivPtr pPriv = GET_BLIT_PRIVATE(pNv); 59fda9279dSmrg BoxPtr pbox; 60fda9279dSmrg int nbox; 61fda9279dSmrg CARD32 dsdx, dtdy; 62fda9279dSmrg CARD32 dst_size, dst_point; 63fda9279dSmrg CARD32 src_point, src_format; 64fda9279dSmrg struct nouveau_pushbuf *push = pNv->pushbuf; 65fda9279dSmrg struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); 66fda9279dSmrg struct nv04_fifo *fifo = pNv->channel->data; 67fda9279dSmrg int dst_format; 68fda9279dSmrg 69fda9279dSmrg if (!NVAccelGetCtxSurf2DFormatFromPixmap(ppix, &dst_format)) 70fda9279dSmrg return BadImplementation; 71fda9279dSmrg 72fda9279dSmrg pbox = REGION_RECTS(clipBoxes); 73fda9279dSmrg nbox = REGION_NUM_RECTS(clipBoxes); 74fda9279dSmrg 75fda9279dSmrg dsdx = (src_w << 20) / drw_w; 76fda9279dSmrg dtdy = (src_h << 20) / drw_h; 77fda9279dSmrg 78fda9279dSmrg dst_size = ((dstBox->y2 - dstBox->y1) << 16) | 79fda9279dSmrg (dstBox->x2 - dstBox->x1); 80fda9279dSmrg dst_point = (dstBox->y1 << 16) | dstBox->x1; 81fda9279dSmrg 82fda9279dSmrg src_point = ((y1 << 4) & 0xffff0000) | (x1 >> 12); 83fda9279dSmrg 84fda9279dSmrg switch(id) { 85fda9279dSmrg case FOURCC_RGB: 86fda9279dSmrg src_format = NV03_SIFM_COLOR_FORMAT_X8R8G8B8; 87fda9279dSmrg break; 88fda9279dSmrg case FOURCC_UYVY: 89fda9279dSmrg src_format = NV03_SIFM_COLOR_FORMAT_YB8V8YA8U8; 90fda9279dSmrg break; 91fda9279dSmrg default: 92fda9279dSmrg src_format = NV03_SIFM_COLOR_FORMAT_V8YB8U8YA8; 93fda9279dSmrg break; 94fda9279dSmrg } 95fda9279dSmrg 96fda9279dSmrg if (!PUSH_SPACE(push, 128)) 97fda9279dSmrg return BadImplementation; 98fda9279dSmrg PUSH_RESET(push); 99fda9279dSmrg 100fda9279dSmrg BEGIN_NV04(push, NV04_SF2D(FORMAT), 4); 101fda9279dSmrg PUSH_DATA (push, dst_format); 102fda9279dSmrg PUSH_DATA (push, (exaGetPixmapPitch(ppix) << 16) | 103fda9279dSmrg exaGetPixmapPitch(ppix)); 104fda9279dSmrg PUSH_MTHDl(push, NV04_SF2D(OFFSET_SOURCE), bo, 0, 105fda9279dSmrg NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); 106fda9279dSmrg PUSH_MTHDl(push, NV04_SF2D(OFFSET_DESTIN), bo, 0, 107fda9279dSmrg NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); 108fda9279dSmrg 109fda9279dSmrg BEGIN_NV04(push, NV01_SUBC(MISC, OBJECT), 1); 110fda9279dSmrg PUSH_DATA (push, pNv->NvScaledImage->handle); 111fda9279dSmrg BEGIN_NV04(push, NV03_SIFM(DMA_IMAGE), 1); 112fda9279dSmrg PUSH_MTHDo(push, NV03_SIFM(DMA_IMAGE), src, NOUVEAU_BO_RD | 113fda9279dSmrg NOUVEAU_BO_VRAM | NOUVEAU_BO_GART, 114fda9279dSmrg fifo->vram, fifo->gart); 115fda9279dSmrg if (pNv->dev->chipset >= 0x05) { 116fda9279dSmrg BEGIN_NV04(push, NV03_SIFM(COLOR_FORMAT), 2); 117fda9279dSmrg PUSH_DATA (push, src_format); 118fda9279dSmrg PUSH_DATA (push, NV03_SIFM_OPERATION_SRCCOPY); 119fda9279dSmrg } else { 120fda9279dSmrg BEGIN_NV04(push, NV03_SIFM(COLOR_FORMAT), 1); 121fda9279dSmrg PUSH_DATA (push, src_format); 122fda9279dSmrg } 123fda9279dSmrg 124fda9279dSmrg nouveau_pushbuf_bufctx(push, pNv->bufctx); 125fda9279dSmrg if (nouveau_pushbuf_validate(push)) { 126fda9279dSmrg nouveau_pushbuf_bufctx(push, NULL); 127fda9279dSmrg return BadAlloc; 128fda9279dSmrg } 129fda9279dSmrg 130fda9279dSmrg if (pPriv->SyncToVBlank) 131fda9279dSmrg NV11SyncToVBlank(ppix, dstBox); 132fda9279dSmrg 133fda9279dSmrg while (nbox--) { 134fda9279dSmrg if (!PUSH_SPACE(push, 16)) { 135fda9279dSmrg nouveau_pushbuf_bufctx(push, NULL); 136fda9279dSmrg return BadImplementation; 137fda9279dSmrg } 138fda9279dSmrg 139fda9279dSmrg BEGIN_NV04(push, NV04_RECT(COLOR1_A), 1); 140fda9279dSmrg PUSH_DATA (push, 0); 141fda9279dSmrg 142fda9279dSmrg BEGIN_NV04(push, NV03_SIFM(CLIP_POINT), 6); 143fda9279dSmrg PUSH_DATA (push, (pbox->y1 << 16) | pbox->x1); 144fda9279dSmrg PUSH_DATA (push, (pbox->y2 - pbox->y1) << 16 | 145fda9279dSmrg (pbox->x2 - pbox->x1)); 146fda9279dSmrg PUSH_DATA (push, dst_point); 147fda9279dSmrg PUSH_DATA (push, dst_size); 148fda9279dSmrg PUSH_DATA (push, dsdx); 149fda9279dSmrg PUSH_DATA (push, dtdy); 150fda9279dSmrg BEGIN_NV04(push, NV03_SIFM(SIZE), 4); 151fda9279dSmrg PUSH_DATA (push, (height << 16) | width); 152fda9279dSmrg PUSH_DATA (push, NV03_SIFM_FORMAT_FILTER_BILINEAR | 153fda9279dSmrg NV03_SIFM_FORMAT_ORIGIN_CENTER | src_pitch); 154fda9279dSmrg PUSH_RELOC(push, src, src_offset, NOUVEAU_BO_LOW, 0, 0); 155fda9279dSmrg PUSH_DATA (push, src_point); 156fda9279dSmrg 157fda9279dSmrg pbox++; 158fda9279dSmrg } 159fda9279dSmrg 160fda9279dSmrg nouveau_pushbuf_bufctx(push, NULL); 161fda9279dSmrg PUSH_KICK(push); 162fda9279dSmrg exaMarkSync(pScrn->pScreen); 163fda9279dSmrg 164fda9279dSmrg pPriv->videoStatus = FREE_TIMER; 165fda9279dSmrg pPriv->videoTime = currentTime.milliseconds + FREE_DELAY; 166fda9279dSmrg extern void NVVideoTimerCallback(ScrnInfoPtr, Time); 167fda9279dSmrg pNv->VideoTimerCallback = NVVideoTimerCallback; 168fda9279dSmrg return Success; 169fda9279dSmrg} 170fda9279dSmrg 171fda9279dSmrg 172fda9279dSmrg/** 173fda9279dSmrg * NVSetBlitPortAttribute 174fda9279dSmrg * sets the attribute "attribute" of port "data" to value "value" 175fda9279dSmrg * supported attributes: 176fda9279dSmrg * - xvSyncToVBlank (values: 0,1) 177fda9279dSmrg * - xvSetDefaults (values: NA; SyncToVBlank will be set, if hardware supports it) 178fda9279dSmrg * 179fda9279dSmrg * @param pScrenInfo 180fda9279dSmrg * @param attribute attribute to set 181fda9279dSmrg * @param value value to which attribute is to be set 182fda9279dSmrg * @param data port from which the attribute is to be set 183fda9279dSmrg * 184fda9279dSmrg * @return Success, if setting is successful 185fda9279dSmrg * BadValue/BadMatch, if value/attribute are invalid 186fda9279dSmrg */ 187fda9279dSmrgint 188fda9279dSmrgNVSetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute, 189fda9279dSmrg INT32 value, pointer data) 190fda9279dSmrg{ 191fda9279dSmrg NVPortPrivPtr pPriv = (NVPortPrivPtr)data; 192fda9279dSmrg NVPtr pNv = NVPTR(pScrn); 193fda9279dSmrg 194fda9279dSmrg if ((attribute == xvSyncToVBlank) && VSYNC_POSSIBLE) { 195fda9279dSmrg if ((value < 0) || (value > 1)) 196fda9279dSmrg return BadValue; 197fda9279dSmrg pPriv->SyncToVBlank = value; 198fda9279dSmrg } else 199fda9279dSmrg if (attribute == xvSetDefaults) { 200fda9279dSmrg pPriv->SyncToVBlank = VSYNC_POSSIBLE; 201fda9279dSmrg } else 202fda9279dSmrg return BadMatch; 203fda9279dSmrg 204fda9279dSmrg return Success; 205fda9279dSmrg} 206fda9279dSmrg 207fda9279dSmrg/** 208fda9279dSmrg * NVGetBlitPortAttribute 209fda9279dSmrg * reads the value of attribute "attribute" from port "data" into INT32 "*value" 210fda9279dSmrg * currently only one attribute supported: xvSyncToVBlank 211fda9279dSmrg * 212fda9279dSmrg * @param pScrn unused 213fda9279dSmrg * @param attribute attribute to be read 214fda9279dSmrg * @param value value of attribute will be stored here 215fda9279dSmrg * @param data port from which attribute will be read 216fda9279dSmrg * @return Success, if queried attribute exists 217fda9279dSmrg */ 218fda9279dSmrgint 219fda9279dSmrgNVGetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute, 220fda9279dSmrg INT32 *value, pointer data) 221fda9279dSmrg{ 222fda9279dSmrg NVPortPrivPtr pPriv = (NVPortPrivPtr)data; 223fda9279dSmrg 224fda9279dSmrg if(attribute == xvSyncToVBlank) 225fda9279dSmrg *value = (pPriv->SyncToVBlank) ? 1 : 0; 226fda9279dSmrg else 227fda9279dSmrg return BadMatch; 228fda9279dSmrg 229fda9279dSmrg return Success; 230fda9279dSmrg} 231fda9279dSmrg 232fda9279dSmrg/** 233fda9279dSmrg * NVStopBlitVideo 234fda9279dSmrg */ 235fda9279dSmrgvoid 236fda9279dSmrgNVStopBlitVideo(ScrnInfoPtr pScrn, pointer data, Bool Exit) 237fda9279dSmrg{ 238fda9279dSmrg} 239fda9279dSmrg 240