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 struct nouveau_pixmap *nvpix;
44 nvpix = exaGetPixmapDriverPrivate(ppix);
45 if (!nvpix || !nvpix->bo)
48 switch (ppix->drawable.depth) {
57 if (!nvpix->bo->tiled)
64 nv50_xv_image_put(ScrnInfoPtr pScrn,
65 struct nouveau_bo *src, int src_offset, int src_offset2,
66 int id, int src_pitch, BoxPtr dstBox,
67 int x1, int y1, int x2, int y2,
68 uint16_t width, uint16_t height,
69 uint16_t src_w, uint16_t src_h,
70 uint16_t drw_w, uint16_t drw_h,
71 RegionPtr clipBoxes, PixmapPtr ppix,
74 NVPtr pNv = NVPTR(pScrn);
75 struct nouveau_channel *chan = pNv->chan;
76 struct nouveau_grobj *tesla = pNv->Nv3D;
81 if (!nv50_xv_check_image_put(ppix))
84 BEGIN_RING(chan, tesla, NV50TCL_RT_ADDRESS_HIGH(0), 5);
85 OUT_PIXMAPh(chan, ppix, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
86 OUT_PIXMAPl(chan, ppix, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
87 switch (ppix->drawable.depth) {
88 case 32: OUT_RING (chan, NV50TCL_RT_FORMAT_32BPP); break;
89 case 24: OUT_RING (chan, NV50TCL_RT_FORMAT_24BPP); break;
90 case 16: OUT_RING (chan, NV50TCL_RT_FORMAT_16BPP); break;
94 BEGIN_RING(chan, tesla, NV50TCL_RT_HORIZ(0), 2);
95 OUT_RING (chan, ppix->drawable.width);
96 OUT_RING (chan, ppix->drawable.height);
97 BEGIN_RING(chan, tesla, 0x1224, 1);
100 BEGIN_RING(chan, tesla, NV50TCL_BLEND_ENABLE(0), 1);
103 BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1);
104 OUT_RING (chan, CB_TIC);
105 BEGIN_RING(chan, tesla, NV50TCL_CB_DATA(0) | 0x40000000, 16);
106 if (id == FOURCC_YV12 || id == FOURCC_I420) {
107 OUT_RING (chan, NV50TIC_0_0_MAPA_C0 | NV50TIC_0_0_TYPEA_UNORM |
108 NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM |
109 NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM |
110 NV50TIC_0_0_MAPB_ZERO | NV50TIC_0_0_TYPEB_UNORM |
112 OUT_RELOCl(chan, src,
113 src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
114 OUT_RING (chan, 0xd0005000);
115 OUT_RING (chan, 0x00300000);
116 OUT_RING (chan, src_w);
117 OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | src_h);
118 OUT_RING (chan, 0x03000000);
119 OUT_RELOCh(chan, src,
120 src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
121 OUT_RING (chan, NV50TIC_0_0_MAPA_C1 | NV50TIC_0_0_TYPEA_UNORM |
122 NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
123 NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM |
124 NV50TIC_0_0_MAPB_ZERO | NV50TIC_0_0_TYPEB_UNORM |
125 NV50TIC_0_0_FMT_8_8);
126 OUT_RELOCl(chan, src,
127 src_offset2, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
128 OUT_RING (chan, 0xd0005000);
129 OUT_RING (chan, 0x00300000);
130 OUT_RING (chan, src_w >> 1);
131 OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | (src_h >> 1));
132 OUT_RING (chan, 0x03000000);
133 OUT_RELOCh(chan, src,
134 src_offset2, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
136 OUT_RING (chan, NV50TIC_0_0_MAPA_C0 | NV50TIC_0_0_TYPEA_UNORM |
137 NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM |
138 NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM |
139 NV50TIC_0_0_MAPB_ZERO | NV50TIC_0_0_TYPEB_UNORM |
140 NV50TIC_0_0_FMT_8_8);
141 OUT_RELOCl(chan, src,
142 src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
143 OUT_RING (chan, 0xd0005000);
144 OUT_RING (chan, 0x00300000);
145 OUT_RING (chan, src_w);
146 OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | src_h);
147 OUT_RING (chan, 0x03000000);
148 OUT_RELOCh(chan, src,
149 src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
150 OUT_RING (chan, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
151 NV50TIC_0_0_MAPR_C1 | NV50TIC_0_0_TYPER_UNORM |
152 NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM |
153 NV50TIC_0_0_MAPB_ZERO | NV50TIC_0_0_TYPEB_UNORM |
154 NV50TIC_0_0_FMT_8_8_8_8);
155 OUT_RELOCl(chan, src,
156 src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
157 OUT_RING (chan, 0xd0005000);
158 OUT_RING (chan, 0x00300000);
159 OUT_RING (chan, (src_w >> 1));
160 OUT_RING (chan, (1 << NV50TIC_0_5_DEPTH_SHIFT) | src_h);
161 OUT_RING (chan, 0x03000000);
162 OUT_RELOCh(chan, src,
163 src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
166 BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1);
167 OUT_RING (chan, CB_TSC);
168 BEGIN_RING(chan, tesla, NV50TCL_CB_DATA(0) | 0x40000000, 16);
169 OUT_RING (chan, NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE |
170 NV50TSC_1_0_WRAPT_CLAMP_TO_EDGE |
171 NV50TSC_1_0_WRAPR_CLAMP_TO_EDGE);
172 OUT_RING (chan, NV50TSC_1_1_MAGF_LINEAR |
173 NV50TSC_1_1_MINF_LINEAR |
174 NV50TSC_1_1_MIPF_NONE);
175 OUT_RING (chan, 0x00000000);
176 OUT_RING (chan, 0x00000000);
177 OUT_RING (chan, 0x00000000);
178 OUT_RING (chan, 0x00000000);
179 OUT_RING (chan, 0x00000000);
180 OUT_RING (chan, 0x00000000);
181 OUT_RING (chan, NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE |
182 NV50TSC_1_0_WRAPT_CLAMP_TO_EDGE |
183 NV50TSC_1_0_WRAPR_CLAMP_TO_EDGE);
184 OUT_RING (chan, NV50TSC_1_1_MAGF_LINEAR |
185 NV50TSC_1_1_MINF_LINEAR |
186 NV50TSC_1_1_MIPF_NONE);
187 OUT_RING (chan, 0x00000000);
188 OUT_RING (chan, 0x00000000);
189 OUT_RING (chan, 0x00000000);
190 OUT_RING (chan, 0x00000000);
191 OUT_RING (chan, 0x00000000);
192 OUT_RING (chan, 0x00000000);
194 BEGIN_RING(chan, tesla, NV50TCL_FP_START_ID, 1);
195 OUT_RING (chan, PFP_NV12);
197 BEGIN_RING(chan, tesla, 0x1334, 1);
200 BEGIN_RING(chan, tesla, 0x1458, 1);
202 BEGIN_RING(chan, tesla, 0x1458, 1);
203 OUT_RING (chan, 0x203);
205 /* These are fixed point values in the 16.16 format. */
206 X1 = (float)(x1>>16)+(float)(x1&0xFFFF)/(float)0x10000;
207 Y1 = (float)(y1>>16)+(float)(y1&0xFFFF)/(float)0x10000;
208 X2 = (float)(x2>>16)+(float)(x2&0xFFFF)/(float)0x10000;
209 Y2 = (float)(y2>>16)+(float)(y2&0xFFFF)/(float)0x10000;
211 BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
212 OUT_RING (chan, NV50TCL_VERTEX_BEGIN_QUADS);
214 pbox = REGION_RECTS(clipBoxes);
215 nbox = REGION_NUM_RECTS(clipBoxes);
217 float tx1=X1+(float)(pbox->x1 - dstBox->x1)*(X2-X1)/(float)(drw_w);
218 float tx2=X1+(float)(pbox->x2 - dstBox->x1)*(src_w)/(float)(drw_w);
219 float ty1=Y1+(float)(pbox->y1 - dstBox->y1)*(Y2-Y1)/(float)(drw_h);
220 float ty2=Y1+(float)(pbox->y2 - dstBox->y1)*(src_h)/(float)(drw_h);
231 VTX2s(pNv, tx1, ty1, tx1, ty1, sx1, sy1);
232 VTX2s(pNv, tx2, ty1, tx2, ty1, sx2, sy1);
233 VTX2s(pNv, tx2, ty2, tx2, ty2, sx2, sy2);
234 VTX2s(pNv, tx1, ty2, tx1, ty2, sx1, sy2);
239 BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
248 nv50_xv_video_stop(ScrnInfoPtr pScrn, pointer data, Bool exit)
253 nv50_xv_port_attribute_set(ScrnInfoPtr pScrn, Atom attribute,
254 INT32 value, pointer data)
260 nv50_xv_port_attribute_get(ScrnInfoPtr pScrn, Atom attribute,
261 INT32 *value, pointer data)