Use stdbool.h types in nv_bios.c
[nouveau] / src / nv04_video_blitter.c
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 "xf86xv.h"
28 #include <X11/extensions/Xv.h>
29 #include "exa.h"
30 #include "damage.h"
31 #include "dixstruct.h"
32 #include "fourcc.h"
33
34 #include "nv_include.h"
35 #include "nv_dma.h"
36
37 #ifndef exaGetDrawablePixmap
38 extern PixmapPtr exaGetDrawablePixmap(DrawablePtr);
39 #endif
40 #ifndef exaPixmapIsOffscreen
41 extern Bool exaPixmapIsOffscreen(PixmapPtr p);
42 #endif
43 /* To support EXA 2.0, 2.1 has this in the header */
44 #ifndef exaMoveInPixmap
45 extern void exaMoveInPixmap(PixmapPtr pPixmap);
46 #endif
47
48 #define FOURCC_RGB 0x0000003
49
50 extern Atom xvSetDefaults, xvSyncToVBlank;
51
52 /**
53  * NVPutBlitImage
54  * 
55  * @param pScrn screen
56  * @param src_offset offset of image data in VRAM
57  * @param id pixel format
58  * @param src_pitch source pitch
59  * @param dstBox 
60  * @param x1
61  * @param y1
62  * @param x2
63  * @param y2
64  * @param width
65  * @param height
66  * @param src_w
67  * @param src_h
68  * @param drw_w
69  * @param drw_h
70  * @param clipBoxes
71  * @param pDraw
72  */
73 void
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,
80                RegionPtr clipBoxes,
81                DrawablePtr pDraw)
82 {
83         NVPtr          pNv   = NVPTR(pScrn);
84         NVPortPrivPtr  pPriv = GET_BLIT_PRIVATE(pNv);
85         BoxPtr         pbox;
86         int            nbox;
87         CARD32         dsdx, dtdy;
88         CARD32         dst_size, dst_point;
89         CARD32         src_point, src_format;
90
91         unsigned int crtcs;
92
93         ScreenPtr pScreen = pScrn->pScreen;
94         PixmapPtr pPix    = exaGetDrawablePixmap(pDraw);
95         int dst_format;
96
97         /* Try to get the dest drawable into vram */
98         if (!exaPixmapIsOffscreen(pPix)) {
99                 exaMoveInPixmap(pPix);
100                 ExaOffscreenMarkUsed(pPix);
101         }
102
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?
106          */
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);
111         }
112
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);
119
120 #ifdef COMPOSITE
121         /* Adjust coordinates if drawing to an offscreen pixmap */
122         if (pPix->screen_x || pPix->screen_y) {
123                 REGION_TRANSLATE(pScrn->pScreen, clipBoxes,
124                                                      -pPix->screen_x,
125                                                      -pPix->screen_y);
126                 dstBox->x1 -= pPix->screen_x;
127                 dstBox->x2 -= pPix->screen_x;
128                 dstBox->y1 -= pPix->screen_y;
129                 dstBox->y2 -= pPix->screen_y;
130         }
131
132         DamageDamageRegion((DrawablePtr)pPix, clipBoxes);
133 #endif
134
135         pbox = REGION_RECTS(clipBoxes);
136         nbox = REGION_NUM_RECTS(clipBoxes);
137
138         dsdx = (src_w << 20) / drw_w;
139         dtdy = (src_h << 20) / drw_h;
140
141         dst_size  = ((dstBox->y2 - dstBox->y1) << 16) |
142                      (dstBox->x2 - dstBox->x1);
143         dst_point = (dstBox->y1 << 16) | dstBox->x1;
144
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);
148
149         switch(id) {
150         case FOURCC_RGB:
151                 src_format =
152                         NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8;
153                 break;
154         case FOURCC_UYVY:
155                 src_format =
156                         NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_YB8V8YA8U8;
157                 break;
158         default:
159                 src_format =
160                         NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_V8YB8U8YA8;
161                 break;
162         }
163
164         if(pPriv->SyncToVBlank) {
165                 crtcs = nv_window_belongs_to_crtc(pScrn, dstBox->x1, dstBox->y1,
166                         dstBox->x2, dstBox->y2);
167
168                 FIRE_RING();
169                 if (crtcs & 0x1)
170                         NVWaitVSync(pScrn, 0);
171                 else if (crtcs & 0x2)
172                         NVWaitVSync(pScrn, 1);
173         }
174
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);
180         } else {
181                 BEGIN_RING(NvScaledImage,
182                                 NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT, 2);
183                 OUT_RING  (src_format);
184         }
185
186         while(nbox--) {
187                 BEGIN_RING(NvRectangle,
188                                 NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1);
189                 OUT_RING  (0);
190
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);
197                 OUT_RING  (dst_size);
198                 OUT_RING  (dsdx);
199                 OUT_RING  (dtdy);
200
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);
207                 pbox++;
208         }
209
210         FIRE_RING();
211
212         exaMarkSync(pScrn->pScreen);
213
214         pPriv->videoStatus = FREE_TIMER;
215         pPriv->videoTime = currentTime.milliseconds + FREE_DELAY;
216         extern void NVVideoTimerCallback(ScrnInfoPtr, Time);
217         pNv->VideoTimerCallback = NVVideoTimerCallback;
218 }
219
220
221 /**
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)
227  * 
228  * @param pScrenInfo
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
232  * 
233  * @return Success, if setting is successful
234  * BadValue/BadMatch, if value/attribute are invalid
235  */
236 int
237 NVSetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
238                        INT32 value, pointer data)
239 {
240         NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
241         NVPtr           pNv = NVPTR(pScrn);
242
243         if ((attribute == xvSyncToVBlank) && pNv->WaitVSyncPossible) {
244                 if ((value < 0) || (value > 1))
245                         return BadValue;
246                 pPriv->SyncToVBlank = value;
247         } else
248         if (attribute == xvSetDefaults) {
249                 pPriv->SyncToVBlank = pNv->WaitVSyncPossible;
250         } else
251                 return BadMatch;
252
253         return Success;
254 }
255
256 /**
257  * NVGetBlitPortAttribute
258  * reads the value of attribute "attribute" from port "data" into INT32 "*value"
259  * currently only one attribute supported: xvSyncToVBlank
260  * 
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
266  */
267 int
268 NVGetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
269                        INT32 *value, pointer data)
270 {
271         NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
272
273         if(attribute == xvSyncToVBlank)
274                 *value = (pPriv->SyncToVBlank) ? 1 : 0;
275         else
276                 return BadMatch;
277
278         return Success;
279 }
280
281 /**
282  * NVStopBlitVideo
283  */
284 void
285 NVStopBlitVideo(ScrnInfoPtr pScrn, pointer data, Bool Exit)
286 {
287 }
288