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