NV50: Some more educated guesses at register names.
[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 /* To support EXA 2.0, 2.1 has this in the header */
38 #ifndef exaMoveInPixmap
39 extern void exaMoveInPixmap(PixmapPtr pPixmap);
40 #endif
41
42 #define FOURCC_RGB 0x0000003
43
44 extern Atom xvSetDefaults, xvSyncToVBlank;
45
46 /**
47  * NVPutBlitImage
48  * 
49  * @param pScrn screen
50  * @param src_offset offset of image data in VRAM
51  * @param id pixel format
52  * @param src_pitch source pitch
53  * @param dstBox 
54  * @param x1
55  * @param y1
56  * @param x2
57  * @param y2
58  * @param width
59  * @param height
60  * @param src_w
61  * @param src_h
62  * @param drw_w
63  * @param drw_h
64  * @param clipBoxes
65  * @param pDraw
66  */
67 void
68 NVPutBlitImage(ScrnInfoPtr pScrn, int src_offset, int id,
69                int src_pitch, BoxPtr dstBox,
70                int x1, int y1, int x2, int y2,
71                short width, short height,
72                short src_w, short src_h,
73                short drw_w, short drw_h,
74                RegionPtr clipBoxes,
75                DrawablePtr pDraw)
76 {
77         NVPtr          pNv   = NVPTR(pScrn);
78         NVPortPrivPtr  pPriv = GET_BLIT_PRIVATE(pNv);
79         BoxPtr         pbox;
80         int            nbox;
81         CARD32         dsdx, dtdy;
82         CARD32         dst_size, dst_point;
83         CARD32         src_point, src_format;
84
85         unsigned int crtcs;
86         PixmapPtr pPix = NVGetDrawablePixmap(pDraw);
87         int dst_format;
88
89         /* This has to be called always, since it does more than just migration. */
90         exaMoveInPixmap(pPix);
91         ExaOffscreenMarkUsed(pPix);
92
93         NVAccelGetCtxSurf2DFormatFromPixmap(pPix, &dst_format);
94         BEGIN_RING(NvContextSurfaces, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
95         OUT_RING  (dst_format);
96         OUT_RING  ((exaGetPixmapPitch(pPix) << 16) | exaGetPixmapPitch(pPix));
97         OUT_PIXMAPl(pPix, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
98         OUT_PIXMAPl(pPix, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
99
100 #ifdef COMPOSITE
101         /* Adjust coordinates if drawing to an offscreen pixmap */
102         if (pPix->screen_x || pPix->screen_y) {
103                 REGION_TRANSLATE(pScrn->pScreen, clipBoxes,
104                                                      -pPix->screen_x,
105                                                      -pPix->screen_y);
106                 dstBox->x1 -= pPix->screen_x;
107                 dstBox->x2 -= pPix->screen_x;
108                 dstBox->y1 -= pPix->screen_y;
109                 dstBox->y2 -= pPix->screen_y;
110         }
111
112         DamageDamageRegion((DrawablePtr)pPix, clipBoxes);
113 #endif
114
115         pbox = REGION_RECTS(clipBoxes);
116         nbox = REGION_NUM_RECTS(clipBoxes);
117
118         dsdx = (src_w << 20) / drw_w;
119         dtdy = (src_h << 20) / drw_h;
120
121         dst_size  = ((dstBox->y2 - dstBox->y1) << 16) |
122                      (dstBox->x2 - dstBox->x1);
123         dst_point = (dstBox->y1 << 16) | dstBox->x1;
124
125         src_pitch |= (NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER |
126                       NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_BILINEAR);
127         src_point = ((y1 << 4) & 0xffff0000) | (x1 >> 12);
128
129         switch(id) {
130         case FOURCC_RGB:
131                 src_format =
132                         NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8;
133                 break;
134         case FOURCC_UYVY:
135                 src_format =
136                         NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_YB8V8YA8U8;
137                 break;
138         default:
139                 src_format =
140                         NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_V8YB8U8YA8;
141                 break;
142         }
143
144         if(pPriv->SyncToVBlank) {
145                 crtcs = nv_window_belongs_to_crtc(pScrn, dstBox->x1, dstBox->y1,
146                         dstBox->x2, dstBox->y2);
147
148                 FIRE_RING();
149                 if (crtcs & 0x1)
150                         NVWaitVSync(pScrn, 0);
151                 else if (crtcs & 0x2)
152                         NVWaitVSync(pScrn, 1);
153         }
154
155         if(pNv->BlendingPossible) {
156                 BEGIN_RING(NvScaledImage,
157                                 NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT, 2);
158                 OUT_RING  (src_format);
159                 OUT_RING  (NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
160         } else {
161                 BEGIN_RING(NvScaledImage,
162                                 NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT, 2);
163                 OUT_RING  (src_format);
164         }
165
166         while(nbox--) {
167                 BEGIN_RING(NvRectangle,
168                                 NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1);
169                 OUT_RING  (0);
170
171                 BEGIN_RING(NvScaledImage,
172                                 NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT, 6);
173                 OUT_RING  ((pbox->y1 << 16) | pbox->x1);
174                 OUT_RING  (((pbox->y2 - pbox->y1) << 16) |
175                                  (pbox->x2 - pbox->x1));
176                 OUT_RING  (dst_point);
177                 OUT_RING  (dst_size);
178                 OUT_RING  (dsdx);
179                 OUT_RING  (dtdy);
180
181                 BEGIN_RING(NvScaledImage,
182                                 NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4);
183                 OUT_RING  ((height << 16) | width);
184                 OUT_RING  (src_pitch);
185                 OUT_RING  (src_offset);
186                 OUT_RING  (src_point);
187                 pbox++;
188         }
189
190         FIRE_RING();
191
192         exaMarkSync(pScrn->pScreen);
193
194         pPriv->videoStatus = FREE_TIMER;
195         pPriv->videoTime = currentTime.milliseconds + FREE_DELAY;
196         extern void NVVideoTimerCallback(ScrnInfoPtr, Time);
197         pNv->VideoTimerCallback = NVVideoTimerCallback;
198 }
199
200
201 /**
202  * NVSetBlitPortAttribute
203  * sets the attribute "attribute" of port "data" to value "value"
204  * supported attributes:
205  * - xvSyncToVBlank (values: 0,1)
206  * - xvSetDefaults (values: NA; SyncToVBlank will be set, if hardware supports it)
207  * 
208  * @param pScrenInfo
209  * @param attribute attribute to set
210  * @param value value to which attribute is to be set
211  * @param data port from which the attribute is to be set
212  * 
213  * @return Success, if setting is successful
214  * BadValue/BadMatch, if value/attribute are invalid
215  */
216 int
217 NVSetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
218                        INT32 value, pointer data)
219 {
220         NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
221         NVPtr           pNv = NVPTR(pScrn);
222
223         if ((attribute == xvSyncToVBlank) && pNv->WaitVSyncPossible) {
224                 if ((value < 0) || (value > 1))
225                         return BadValue;
226                 pPriv->SyncToVBlank = value;
227         } else
228         if (attribute == xvSetDefaults) {
229                 pPriv->SyncToVBlank = pNv->WaitVSyncPossible;
230         } else
231                 return BadMatch;
232
233         return Success;
234 }
235
236 /**
237  * NVGetBlitPortAttribute
238  * reads the value of attribute "attribute" from port "data" into INT32 "*value"
239  * currently only one attribute supported: xvSyncToVBlank
240  * 
241  * @param pScrn unused
242  * @param attribute attribute to be read
243  * @param value value of attribute will be stored here
244  * @param data port from which attribute will be read
245  * @return Success, if queried attribute exists
246  */
247 int
248 NVGetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
249                        INT32 *value, pointer data)
250 {
251         NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
252
253         if(attribute == xvSyncToVBlank)
254                 *value = (pPriv->SyncToVBlank) ? 1 : 0;
255         else
256                 return BadMatch;
257
258         return Success;
259 }
260
261 /**
262  * NVStopBlitVideo
263  */
264 void
265 NVStopBlitVideo(ScrnInfoPtr pScrn, pointer data, Bool Exit)
266 {
267 }
268