Merge remote-tracking branch 'jekstrand/wip/i965-uniforms' into vulkan
[mesa.git] / src / gallium / drivers / nouveau / nv50 / nv98_video.c
1 /*
2 * Copyright 2011-2013 Maarten Lankhorst, Ilia Mirkin
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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23 #include "nv50/nv98_video.h"
24
25 #include "util/u_sampler.h"
26 #include "util/u_format.h"
27
28 #include <nvif/class.h>
29
30 static void
31 nv98_decoder_decode_bitstream(struct pipe_video_codec *decoder,
32 struct pipe_video_buffer *video_target,
33 struct pipe_picture_desc *picture,
34 unsigned num_buffers,
35 const void *const *data,
36 const unsigned *num_bytes)
37 {
38 struct nouveau_vp3_decoder *dec = (struct nouveau_vp3_decoder *)decoder;
39 struct nouveau_vp3_video_buffer *target = (struct nouveau_vp3_video_buffer *)video_target;
40 uint32_t comm_seq = ++dec->fence_seq;
41 union pipe_desc desc;
42
43 unsigned vp_caps, is_ref, ret;
44 struct nouveau_vp3_video_buffer *refs[16] = {};
45
46 desc.base = picture;
47
48 assert(target->base.buffer_format == PIPE_FORMAT_NV12);
49
50 ret = nv98_decoder_bsp(dec, desc, target, comm_seq,
51 num_buffers, data, num_bytes,
52 &vp_caps, &is_ref, refs);
53
54 /* did we decode bitstream correctly? */
55 assert(ret == 2);
56
57 nv98_decoder_vp(dec, desc, target, comm_seq, vp_caps, is_ref, refs);
58 nv98_decoder_ppp(dec, desc, target, comm_seq);
59 }
60
61 static const struct nouveau_mclass
62 nv98_decoder_msvld[] = {
63 { G98_MSVLD, -1 },
64 { IGT21A_MSVLD, -1 },
65 { GT212_MSVLD, -1 },
66 {}
67 };
68
69 static const struct nouveau_mclass
70 nv98_decoder_mspdec[] = {
71 { G98_MSPDEC, -1 },
72 { GT212_MSPDEC, -1 },
73 {}
74 };
75
76 static const struct nouveau_mclass
77 nv98_decoder_msppp[] = {
78 { G98_MSPPP, -1 },
79 { GT212_MSPPP, -1 },
80 {}
81 };
82
83 struct pipe_video_codec *
84 nv98_create_decoder(struct pipe_context *context,
85 const struct pipe_video_codec *templ)
86 {
87 struct nouveau_screen *screen = &((struct nv50_context *)context)->screen->base;
88 struct nouveau_vp3_decoder *dec;
89 struct nouveau_pushbuf **push;
90 struct nv04_fifo nv04_data = {.vram = 0xbeef0201, .gart = 0xbeef0202};
91
92 int ret, i;
93 uint32_t codec = 1, ppp_codec = 3;
94 uint32_t timeout;
95 u32 tmp_size = 0;
96
97 if (getenv("XVMC_VL"))
98 return vl_create_decoder(context, templ);
99
100 if (templ->entrypoint != PIPE_VIDEO_ENTRYPOINT_BITSTREAM) {
101 debug_printf("%x\n", templ->entrypoint);
102 return NULL;
103 }
104
105 dec = CALLOC_STRUCT(nouveau_vp3_decoder);
106 if (!dec)
107 return NULL;
108 dec->client = screen->client;
109 dec->base = *templ;
110 nouveau_vp3_decoder_init_common(&dec->base);
111
112 dec->bsp_idx = 5;
113 dec->vp_idx = 6;
114 dec->ppp_idx = 7;
115
116 ret = nouveau_object_new(&screen->device->object, 0,
117 NOUVEAU_FIFO_CHANNEL_CLASS,
118 &nv04_data, sizeof(nv04_data), &dec->channel[0]);
119
120 if (!ret)
121 ret = nouveau_pushbuf_new(screen->client, dec->channel[0], 4,
122 32 * 1024, true, &dec->pushbuf[0]);
123
124 for (i = 1; i < 3; ++i) {
125 dec->channel[i] = dec->channel[0];
126 dec->pushbuf[i] = dec->pushbuf[0];
127 }
128 push = dec->pushbuf;
129
130 if (!ret) {
131 ret = nouveau_object_mclass(dec->channel[0], nv98_decoder_msvld);
132 if (ret >= 0) {
133 ret = nouveau_object_new(dec->channel[0], 0xbeef85b1,
134 nv98_decoder_msvld[ret].oclass, NULL, 0,
135 &dec->bsp);
136 }
137 }
138
139 if (!ret) {
140 ret = nouveau_object_mclass(dec->channel[1], nv98_decoder_mspdec);
141 if (ret >= 0) {
142 ret = nouveau_object_new(dec->channel[1], 0xbeef85b2,
143 nv98_decoder_mspdec[ret].oclass, NULL, 0,
144 &dec->vp);
145 }
146 }
147
148 if (!ret) {
149 ret = nouveau_object_mclass(dec->channel[2], nv98_decoder_msppp);
150 if (ret >= 0) {
151 ret = nouveau_object_new(dec->channel[2], 0xbeef85b3,
152 nv98_decoder_msppp[ret].oclass, NULL, 0,
153 &dec->ppp);
154 }
155 }
156
157 if (ret)
158 goto fail;
159
160 BEGIN_NV04(push[0], SUBC_BSP(NV01_SUBCHAN_OBJECT), 1);
161 PUSH_DATA (push[0], dec->bsp->handle);
162
163 BEGIN_NV04(push[0], SUBC_BSP(0x180), 5);
164 for (i = 0; i < 5; i++)
165 PUSH_DATA (push[0], nv04_data.vram);
166
167 BEGIN_NV04(push[1], SUBC_VP(NV01_SUBCHAN_OBJECT), 1);
168 PUSH_DATA (push[1], dec->vp->handle);
169
170 BEGIN_NV04(push[1], SUBC_VP(0x180), 6);
171 for (i = 0; i < 6; i++)
172 PUSH_DATA (push[1], nv04_data.vram);
173
174 BEGIN_NV04(push[2], SUBC_PPP(NV01_SUBCHAN_OBJECT), 1);
175 PUSH_DATA (push[2], dec->ppp->handle);
176
177 BEGIN_NV04(push[2], SUBC_PPP(0x180), 5);
178 for (i = 0; i < 5; i++)
179 PUSH_DATA (push[2], nv04_data.vram);
180
181 dec->base.context = context;
182 dec->base.decode_bitstream = nv98_decoder_decode_bitstream;
183
184 for (i = 0; i < NOUVEAU_VP3_VIDEO_QDEPTH && !ret; ++i)
185 ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM,
186 0, 1 << 20, NULL, &dec->bsp_bo[i]);
187 if (!ret)
188 ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM,
189 0x100, 4 << 20, NULL, &dec->inter_bo[0]);
190 if (!ret)
191 nouveau_bo_ref(dec->inter_bo[0], &dec->inter_bo[1]);
192 if (ret)
193 goto fail;
194
195 switch (u_reduce_video_profile(templ->profile)) {
196 case PIPE_VIDEO_FORMAT_MPEG12: {
197 codec = 1;
198 assert(templ->max_references <= 2);
199 break;
200 }
201 case PIPE_VIDEO_FORMAT_MPEG4: {
202 codec = 4;
203 tmp_size = mb(templ->height)*16 * mb(templ->width)*16;
204 assert(templ->max_references <= 2);
205 break;
206 }
207 case PIPE_VIDEO_FORMAT_VC1: {
208 ppp_codec = codec = 2;
209 tmp_size = mb(templ->height)*16 * mb(templ->width)*16;
210 assert(templ->max_references <= 2);
211 break;
212 }
213 case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
214 codec = 3;
215 dec->tmp_stride = 16 * mb_half(templ->width) * nouveau_vp3_video_align(templ->height) * 3 / 2;
216 tmp_size = dec->tmp_stride * (templ->max_references + 1);
217 assert(templ->max_references <= 16);
218 break;
219 }
220 default:
221 fprintf(stderr, "invalid codec\n");
222 goto fail;
223 }
224
225 ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM, 0,
226 0x4000, NULL, &dec->fw_bo);
227 if (ret)
228 goto fail;
229
230 ret = nouveau_vp3_load_firmware(dec, templ->profile, screen->device->chipset);
231 if (ret)
232 goto fw_fail;
233
234 if (codec != 3) {
235 ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM, 0,
236 0x400, NULL, &dec->bitplane_bo);
237 if (ret)
238 goto fail;
239 }
240
241 dec->ref_stride = mb(templ->width)*16 * (mb_half(templ->height)*32 + nouveau_vp3_video_align(templ->height)/2);
242 ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM, 0,
243 dec->ref_stride * (templ->max_references+2) + tmp_size,
244 NULL, &dec->ref_bo);
245 if (ret)
246 goto fail;
247
248 timeout = 0;
249
250 BEGIN_NV04(push[0], SUBC_BSP(0x200), 2);
251 PUSH_DATA (push[0], codec);
252 PUSH_DATA (push[0], timeout);
253
254 BEGIN_NV04(push[1], SUBC_VP(0x200), 2);
255 PUSH_DATA (push[1], codec);
256 PUSH_DATA (push[1], timeout);
257
258 BEGIN_NV04(push[2], SUBC_PPP(0x200), 2);
259 PUSH_DATA (push[2], ppp_codec);
260 PUSH_DATA (push[2], timeout);
261
262 ++dec->fence_seq;
263
264 #if NOUVEAU_VP3_DEBUG_FENCE
265 ret = nouveau_bo_new(screen->device, NOUVEAU_BO_GART|NOUVEAU_BO_MAP,
266 0, 0x1000, NULL, &dec->fence_bo);
267 if (ret)
268 goto fail;
269
270 nouveau_bo_map(dec->fence_bo, NOUVEAU_BO_RDWR, screen->client);
271 dec->fence_map = dec->fence_bo->map;
272 dec->fence_map[0] = dec->fence_map[4] = dec->fence_map[8] = 0;
273 dec->comm = (struct comm *)(dec->fence_map + (COMM_OFFSET/sizeof(*dec->fence_map)));
274
275 /* So lets test if the fence is working? */
276 nouveau_pushbuf_space(push[0], 6, 1, 0);
277 PUSH_REFN (push[0], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
278 BEGIN_NV04(push[0], SUBC_BSP(0x240), 3);
279 PUSH_DATAh(push[0], dec->fence_bo->offset);
280 PUSH_DATA (push[0], dec->fence_bo->offset);
281 PUSH_DATA (push[0], dec->fence_seq);
282
283 BEGIN_NV04(push[0], SUBC_BSP(0x304), 1);
284 PUSH_DATA (push[0], 0);
285 PUSH_KICK (push[0]);
286
287 nouveau_pushbuf_space(push[1], 6, 1, 0);
288 PUSH_REFN (push[1], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
289 BEGIN_NV04(push[1], SUBC_VP(0x240), 3);
290 PUSH_DATAh(push[1], (dec->fence_bo->offset + 0x10));
291 PUSH_DATA (push[1], (dec->fence_bo->offset + 0x10));
292 PUSH_DATA (push[1], dec->fence_seq);
293
294 BEGIN_NV04(push[1], SUBC_VP(0x304), 1);
295 PUSH_DATA (push[1], 0);
296 PUSH_KICK (push[1]);
297
298 nouveau_pushbuf_space(push[2], 6, 1, 0);
299 PUSH_REFN (push[2], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
300 BEGIN_NV04(push[2], SUBC_PPP(0x240), 3);
301 PUSH_DATAh(push[2], (dec->fence_bo->offset + 0x20));
302 PUSH_DATA (push[2], (dec->fence_bo->offset + 0x20));
303 PUSH_DATA (push[2], dec->fence_seq);
304
305 BEGIN_NV04(push[2], SUBC_PPP(0x304), 1);
306 PUSH_DATA (push[2], 0);
307 PUSH_KICK (push[2]);
308
309 usleep(100);
310 while (dec->fence_seq > dec->fence_map[0] ||
311 dec->fence_seq > dec->fence_map[4] ||
312 dec->fence_seq > dec->fence_map[8]) {
313 debug_printf("%u: %u %u %u\n", dec->fence_seq, dec->fence_map[0], dec->fence_map[4], dec->fence_map[8]);
314 usleep(100);
315 }
316 debug_printf("%u: %u %u %u\n", dec->fence_seq, dec->fence_map[0], dec->fence_map[4], dec->fence_map[8]);
317 #endif
318
319 return &dec->base;
320
321 fw_fail:
322 debug_printf("Cannot create decoder without firmware..\n");
323 dec->base.destroy(&dec->base);
324 return NULL;
325
326 fail:
327 debug_printf("Creation failed: %s (%i)\n", strerror(-ret), ret);
328 dec->base.destroy(&dec->base);
329 return NULL;
330 }
331
332 struct pipe_video_buffer *
333 nv98_video_buffer_create(struct pipe_context *pipe,
334 const struct pipe_video_buffer *templat)
335 {
336 return nouveau_vp3_video_buffer_create(
337 pipe, templat, NV50_RESOURCE_FLAG_VIDEO);
338 }