2 * Copyright 2007 Arthur Huillet
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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
28 #include <X11/extensions/Xv.h>
31 #include "dixstruct.h"
34 #include "nv_include.h"
37 #ifndef exaGetDrawablePixmap
38 extern PixmapPtr exaGetDrawablePixmap(DrawablePtr);
40 #ifndef exaPixmapIsOffscreen
41 extern Bool exaPixmapIsOffscreen(PixmapPtr p);
43 /* To support EXA 2.0, 2.1 has this in the header */
44 #ifndef exaMoveInPixmap
45 extern void exaMoveInPixmap(PixmapPtr pPixmap);
48 #define FOURCC_RGB 0x0000003
50 extern Atom xvSetDefaults, xvSyncToVBlank;
56 * @param src_offset offset of image data in VRAM
57 * @param id pixel format
58 * @param src_pitch source pitch
74 NVPutBlitImage(ScrnInfoPtr pScrn, int src_offset, int id,
75 int src_pitch, BoxPtr dstBox,
76 int x1, int y1, int x2, int y2,
77 short width, short height,
78 short src_w, short src_h,
79 short drw_w, short drw_h,
83 NVPtr pNv = NVPTR(pScrn);
84 NVPortPrivPtr pPriv = GET_BLIT_PRIVATE(pNv);
88 CARD32 dst_size, dst_point;
89 CARD32 src_point, src_format;
93 ScreenPtr pScreen = pScrn->pScreen;
94 PixmapPtr pPix = exaGetDrawablePixmap(pDraw);
97 /* Try to get the dest drawable into vram */
98 if (!exaPixmapIsOffscreen(pPix)) {
99 exaMoveInPixmap(pPix);
100 ExaOffscreenMarkUsed(pPix);
103 /* If we failed, draw directly onto the screen pixmap.
104 * Not sure if this is the best approach, maybe failing
105 * with BadAlloc would be better?
107 if (!exaPixmapIsOffscreen(pPix)) {
108 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
109 "XV: couldn't move dst surface into vram\n");
110 pPix = pScreen->GetScreenPixmap(pScreen);
113 NVAccelGetCtxSurf2DFormatFromPixmap(pPix, &dst_format);
114 BEGIN_RING(NvContextSurfaces, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
115 OUT_RING (dst_format);
116 OUT_RING ((exaGetPixmapPitch(pPix) << 16) | exaGetPixmapPitch(pPix));
117 OUT_PIXMAPl(pPix, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
118 OUT_PIXMAPl(pPix, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
121 /* Adjust coordinates if drawing to an offscreen pixmap */
122 if (pPix->screen_x || pPix->screen_y) {
123 REGION_TRANSLATE(pScrn->pScreen, clipBoxes,
126 dstBox->x1 -= pPix->screen_x;
127 dstBox->x2 -= pPix->screen_x;
128 dstBox->y1 -= pPix->screen_y;
129 dstBox->y2 -= pPix->screen_y;
132 DamageDamageRegion((DrawablePtr)pPix, clipBoxes);
135 pbox = REGION_RECTS(clipBoxes);
136 nbox = REGION_NUM_RECTS(clipBoxes);
138 dsdx = (src_w << 20) / drw_w;
139 dtdy = (src_h << 20) / drw_h;
141 dst_size = ((dstBox->y2 - dstBox->y1) << 16) |
142 (dstBox->x2 - dstBox->x1);
143 dst_point = (dstBox->y1 << 16) | dstBox->x1;
145 src_pitch |= (NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER |
146 NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_BILINEAR);
147 src_point = ((y1 << 4) & 0xffff0000) | (x1 >> 12);
152 NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8;
156 NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_YB8V8YA8U8;
160 NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_V8YB8U8YA8;
164 if(pPriv->SyncToVBlank) {
165 crtcs = nv_window_belongs_to_crtc(pScrn, dstBox->x1, dstBox->y1,
166 dstBox->x2, dstBox->y2);
170 NVWaitVSync(pScrn, 0);
171 else if (crtcs & 0x2)
172 NVWaitVSync(pScrn, 1);
175 if(pNv->BlendingPossible) {
176 BEGIN_RING(NvScaledImage,
177 NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT, 2);
178 OUT_RING (src_format);
179 OUT_RING (NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
181 BEGIN_RING(NvScaledImage,
182 NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT, 2);
183 OUT_RING (src_format);
187 BEGIN_RING(NvRectangle,
188 NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1);
191 BEGIN_RING(NvScaledImage,
192 NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT, 6);
193 OUT_RING ((pbox->y1 << 16) | pbox->x1);
194 OUT_RING (((pbox->y2 - pbox->y1) << 16) |
195 (pbox->x2 - pbox->x1));
196 OUT_RING (dst_point);
201 BEGIN_RING(NvScaledImage,
202 NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4);
203 OUT_RING ((height << 16) | width);
204 OUT_RING (src_pitch);
205 OUT_RING (src_offset);
206 OUT_RING (src_point);
212 exaMarkSync(pScrn->pScreen);
214 pPriv->videoStatus = FREE_TIMER;
215 pPriv->videoTime = currentTime.milliseconds + FREE_DELAY;
216 extern void NVVideoTimerCallback(ScrnInfoPtr, Time);
217 pNv->VideoTimerCallback = NVVideoTimerCallback;
222 * NVSetBlitPortAttribute
223 * sets the attribute "attribute" of port "data" to value "value"
224 * supported attributes:
225 * - xvSyncToVBlank (values: 0,1)
226 * - xvSetDefaults (values: NA; SyncToVBlank will be set, if hardware supports it)
229 * @param attribute attribute to set
230 * @param value value to which attribute is to be set
231 * @param data port from which the attribute is to be set
233 * @return Success, if setting is successful
234 * BadValue/BadMatch, if value/attribute are invalid
237 NVSetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
238 INT32 value, pointer data)
240 NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
241 NVPtr pNv = NVPTR(pScrn);
243 if ((attribute == xvSyncToVBlank) && pNv->WaitVSyncPossible) {
244 if ((value < 0) || (value > 1))
246 pPriv->SyncToVBlank = value;
248 if (attribute == xvSetDefaults) {
249 pPriv->SyncToVBlank = pNv->WaitVSyncPossible;
257 * NVGetBlitPortAttribute
258 * reads the value of attribute "attribute" from port "data" into INT32 "*value"
259 * currently only one attribute supported: xvSyncToVBlank
261 * @param pScrn unused
262 * @param attribute attribute to be read
263 * @param value value of attribute will be stored here
264 * @param data port from which attribute will be read
265 * @return Success, if queried attribute exists
268 NVGetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
269 INT32 *value, pointer data)
271 NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
273 if(attribute == xvSyncToVBlank)
274 *value = (pPriv->SyncToVBlank) ? 1 : 0;
285 NVStopBlitVideo(ScrnInfoPtr pScrn, pointer data, Bool Exit)