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