2 * Copyright 2008 Ben Skeggs
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"
36 #include "nv50_accel.h"
37 #include "nv50_texture.h"
40 nv50_xv_check_image_put(PixmapPtr ppix)
42 ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
43 NVPtr pNv = NVPTR(pScrn);
45 switch (ppix->drawable.depth) {
54 if (exaGetPixmapOffset(ppix) < pNv->EXADriverPtr->offScreenBase)
61 nv50_xv_image_put(ScrnInfoPtr pScrn,
62 struct nouveau_bo *src, int src_offset, int src_offset2,
63 int id, int src_pitch, BoxPtr dstBox,
64 int x1, int y1, int x2, int y2,
65 uint16_t width, uint16_t height,
66 uint16_t src_w, uint16_t src_h,
67 uint16_t drw_w, uint16_t drw_h,
68 RegionPtr clipBoxes, PixmapPtr ppix,
71 NVPtr pNv = NVPTR(pScrn);
72 struct nouveau_channel *chan = pNv->chan;
73 struct nouveau_grobj *tesla = pNv->Nv3D;
78 if (!nv50_xv_check_image_put(ppix))
81 BEGIN_RING(chan, tesla, NV50TCL_RT_ADDRESS_HIGH(0), 5);
82 OUT_PIXMAPh(chan, ppix, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
83 OUT_PIXMAPl(chan, ppix, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
84 switch (ppix->drawable.depth) {
85 case 32: OUT_RING (chan, NV50TCL_RT_FORMAT_32BPP); break;
86 case 24: OUT_RING (chan, NV50TCL_RT_FORMAT_24BPP); break;
87 case 16: OUT_RING (chan, NV50TCL_RT_FORMAT_16BPP); break;
91 BEGIN_RING(chan, tesla, NV50TCL_RT_HORIZ(0), 2);
92 OUT_RING (chan, ppix->drawable.width);
93 OUT_RING (chan, ppix->drawable.height);
94 BEGIN_RING(chan, tesla, 0x1224, 1);
97 BEGIN_RING(chan, tesla, NV50TCL_BLEND_ENABLE(0), 1);
100 BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1);
101 OUT_RING (chan, CB_TIC);
102 BEGIN_RING(chan, tesla, NV50TCL_CB_DATA(0) | 0x40000000, 16);
103 if (id == FOURCC_YV12 || id == FOURCC_I420) {
104 OUT_RING (chan, NV50TIC_0_0_MAPA_C0 | NV50TIC_0_0_TYPEA_UNORM |
105 NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM |
106 NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM |
107 NV50TIC_0_0_MAPB_ZERO | NV50TIC_0_0_TYPEB_UNORM |
109 OUT_RELOCl(chan, src,
110 src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
111 OUT_RING (chan, 0xd0005000);
112 OUT_RING (chan, 0x00300000);
113 OUT_RING (chan, src_w);
114 OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | src_h);
115 OUT_RING (chan, 0x03000000);
116 OUT_RELOCh(chan, src,
117 src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
118 OUT_RING (chan, NV50TIC_0_0_MAPA_C1 | NV50TIC_0_0_TYPEA_UNORM |
119 NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
120 NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM |
121 NV50TIC_0_0_MAPB_ZERO | NV50TIC_0_0_TYPEB_UNORM |
122 NV50TIC_0_0_FMT_8_8);
123 OUT_RELOCl(chan, src,
124 src_offset2, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
125 OUT_RING (chan, 0xd0005000);
126 OUT_RING (chan, 0x00300000);
127 OUT_RING (chan, src_w >> 1);
128 OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | (src_h >> 1));
129 OUT_RING (chan, 0x03000000);
130 OUT_RELOCh(chan, src,
131 src_offset2, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
133 OUT_RING (chan, NV50TIC_0_0_MAPA_C0 | NV50TIC_0_0_TYPEA_UNORM |
134 NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM |
135 NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM |
136 NV50TIC_0_0_MAPB_ZERO | NV50TIC_0_0_TYPEB_UNORM |
137 NV50TIC_0_0_FMT_8_8);
138 OUT_RELOCl(chan, src,
139 src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
140 OUT_RING (chan, 0xd0005000);
141 OUT_RING (chan, 0x00300000);
142 OUT_RING (chan, src_w);
143 OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | src_h);
144 OUT_RING (chan, 0x03000000);
145 OUT_RELOCh(chan, src,
146 src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
147 OUT_RING (chan, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
148 NV50TIC_0_0_MAPR_C1 | NV50TIC_0_0_TYPER_UNORM |
149 NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM |
150 NV50TIC_0_0_MAPB_ZERO | NV50TIC_0_0_TYPEB_UNORM |
151 NV50TIC_0_0_FMT_8_8_8_8);
152 OUT_RELOCl(chan, src,
153 src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
154 OUT_RING (chan, 0xd0005000);
155 OUT_RING (chan, 0x00300000);
156 OUT_RING (chan, (src_w >> 1));
157 OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | src_h);
158 OUT_RING (chan, 0x03000000);
159 OUT_RELOCh(chan, src,
160 src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
163 BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1);
164 OUT_RING (chan, CB_TSC);
165 BEGIN_RING(chan, tesla, NV50TCL_CB_DATA(0) | 0x40000000, 16);
166 OUT_RING (chan, NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE |
167 NV50TSC_1_0_WRAPT_CLAMP_TO_EDGE |
168 NV50TSC_1_0_WRAPR_CLAMP_TO_EDGE);
169 OUT_RING (chan, NV50TSC_1_1_MAGF_LINEAR |
170 NV50TSC_1_1_MINF_LINEAR |
171 NV50TSC_1_1_MIPF_NONE);
172 OUT_RING (chan, 0x00000000);
173 OUT_RING (chan, 0x00000000);
174 OUT_RING (chan, 0x00000000);
175 OUT_RING (chan, 0x00000000);
176 OUT_RING (chan, 0x00000000);
177 OUT_RING (chan, 0x00000000);
178 OUT_RING (chan, NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE |
179 NV50TSC_1_0_WRAPT_CLAMP_TO_EDGE |
180 NV50TSC_1_0_WRAPR_CLAMP_TO_EDGE);
181 OUT_RING (chan, NV50TSC_1_1_MAGF_LINEAR |
182 NV50TSC_1_1_MINF_LINEAR |
183 NV50TSC_1_1_MIPF_NONE);
184 OUT_RING (chan, 0x00000000);
185 OUT_RING (chan, 0x00000000);
186 OUT_RING (chan, 0x00000000);
187 OUT_RING (chan, 0x00000000);
188 OUT_RING (chan, 0x00000000);
189 OUT_RING (chan, 0x00000000);
191 BEGIN_RING(chan, tesla, NV50TCL_FP_START_ID, 1);
192 OUT_RING (chan, PFP_NV12);
194 BEGIN_RING(chan, tesla, 0x1334, 1);
197 BEGIN_RING(chan, tesla, 0x1458, 1);
199 BEGIN_RING(chan, tesla, 0x1458, 1);
200 OUT_RING (chan, 0x203);
202 /* These are fixed point values in the 16.16 format. */
203 X1 = (float)(x1>>16)+(float)(x1&0xFFFF)/(float)0x10000;
204 Y1 = (float)(y1>>16)+(float)(y1&0xFFFF)/(float)0x10000;
205 X2 = (float)(x2>>16)+(float)(x2&0xFFFF)/(float)0x10000;
206 Y2 = (float)(y2>>16)+(float)(y2&0xFFFF)/(float)0x10000;
208 BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
209 OUT_RING (chan, NV50TCL_VERTEX_BEGIN_QUADS);
211 pbox = REGION_RECTS(clipBoxes);
212 nbox = REGION_NUM_RECTS(clipBoxes);
214 float tx1=X1+(float)(pbox->x1 - dstBox->x1)*(X2-X1)/(float)(drw_w);
215 float tx2=X1+(float)(pbox->x2 - dstBox->x1)*(src_w)/(float)(drw_w);
216 float ty1=Y1+(float)(pbox->y1 - dstBox->y1)*(Y2-Y1)/(float)(drw_h);
217 float ty2=Y1+(float)(pbox->y2 - dstBox->y1)*(src_h)/(float)(drw_h);
228 VTX2s(pNv, tx1, ty1, tx1, ty1, sx1, sy1);
229 VTX2s(pNv, tx2, ty1, tx2, ty1, sx2, sy1);
230 VTX2s(pNv, tx2, ty2, tx2, ty2, sx2, sy2);
231 VTX2s(pNv, tx1, ty2, tx1, ty2, sx1, sy2);
236 BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
245 nv50_xv_video_stop(ScrnInfoPtr pScrn, pointer data, Bool exit)
250 nv50_xv_port_attribute_set(ScrnInfoPtr pScrn, Atom attribute,
251 INT32 value, pointer data)
257 nv50_xv_port_attribute_get(ScrnInfoPtr pScrn, Atom attribute,
258 INT32 *value, pointer data)