42bc102b1cf5d0f4a74570ef53310c197264907f
[mesa.git] / src / gallium / drivers / nouveau / nouveau_video.c
1 /*
2 * Copyright 2011 Maarten Lankhorst
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 #include "vl/vl_decoder.h"
24 #include "vl/vl_video_buffer.h"
25
26 #include "nouveau_screen.h"
27 #include "nouveau_context.h"
28 #include "nouveau_video.h"
29
30 #include "nouveau/nouveau_bo.h"
31 #include "nouveau/nouveau_buffer.h"
32 #include "util/u_video.h"
33 #include "util/u_format.h"
34 #include "util/u_sampler.h"
35 #include "nouveau/nouveau_device.h"
36 #include "nouveau_winsys.h"
37
38 static int
39 nouveau_vpe_init(struct nouveau_decoder *dec) {
40 int ret;
41 if (dec->cmds)
42 return 0;
43 ret = nouveau_bo_map(dec->cmd_bo, NOUVEAU_BO_RDWR);
44 if (ret) {
45 debug_printf("Mapping cmd bo: %s\n", strerror(-ret));
46 return ret;
47 }
48 ret = nouveau_bo_map(dec->data_bo, NOUVEAU_BO_RDWR);
49 if (ret) {
50 nouveau_bo_unmap(dec->cmd_bo);
51 debug_printf("Mapping data bo: %s\n", strerror(-ret));
52 return ret;
53 }
54 dec->cmds = dec->cmd_bo->map;
55 dec->data = dec->data_bo->map;
56 return ret;
57 }
58
59 static void
60 nouveau_vpe_synch(struct nouveau_decoder *dec) {
61 struct nouveau_channel *chan = dec->screen->channel;
62 #if 0
63 if (dec->fence_map) {
64 BEGIN_RING(chan, dec->mpeg, NV84_MPEG_QUERY_COUNTER, 1);
65 OUT_RING(chan, ++dec->fence_seq);
66 FIRE_RING(chan);
67 while (dec->fence_map[0] != dec->fence_seq)
68 usleep(1000);
69 } else
70 #endif
71 FIRE_RING(chan);
72 }
73
74 static void
75 nouveau_vpe_fini(struct nouveau_decoder *dec) {
76 struct nouveau_channel *chan = dec->screen->channel;
77 if (!dec->cmds)
78 return;
79
80 nouveau_bo_unmap(dec->data_bo);
81 nouveau_bo_unmap(dec->cmd_bo);
82
83 MARK_RING(chan, 8, 2);
84 BEGIN_RING(chan, dec->mpeg, NV31_MPEG_CMD_OFFSET, 2);
85 OUT_RELOCl(chan, dec->cmd_bo, 0, NOUVEAU_BO_RD|NOUVEAU_BO_GART);
86 OUT_RING(chan, dec->ofs * 4);
87
88 BEGIN_RING(chan, dec->mpeg, NV31_MPEG_DATA_OFFSET, 2);
89 OUT_RELOCl(chan, dec->data_bo, 0, NOUVEAU_BO_RD|NOUVEAU_BO_GART);
90 OUT_RING(chan, dec->data_pos * 4);
91
92 BEGIN_RING(chan, dec->mpeg, NV31_MPEG_EXEC, 1);
93 OUT_RING(chan, 1);
94
95 nouveau_vpe_synch(dec);
96 dec->ofs = dec->data_pos = dec->num_surfaces = 0;
97 dec->cmds = dec->data = NULL;
98 dec->current = dec->future = dec->past = 8;
99 }
100
101 static INLINE void
102 nouveau_vpe_mb_dct_blocks(struct nouveau_decoder *dec, const struct pipe_mpeg12_macroblock *mb)
103 {
104 int cbb;
105 unsigned cbp = mb->coded_block_pattern;
106 short *db = mb->blocks;
107 for (cbb = 0x20; cbb > 0; cbb >>= 1) {
108 if (cbb & cbp) {
109 static const int lookup[64] = {
110 0, 1, 8,16, 9, 2, 3,10,
111 17,24,32,25,18,11, 4, 5,
112 12,19,26,33,40,48,41,34,
113 27,20,13, 6, 7,14,21,28,
114 35,42,49,56,57,50,43,36,
115 29,22,15,23,30,37,44,51,
116 58,59,52,45,38,31,39,46,
117 53,60,61,54,47,55,62,63
118 };
119 int i, j = 0, found = 0;
120 for (i = 0; i < 64; ++i) {
121 if (!db[lookup[i]]) { j += 2; continue; }
122 dec->data[dec->data_pos++] = (db[lookup[i]] << 16) | j;
123 j = 0;
124 found = 1;
125 }
126 if (found)
127 dec->data[dec->data_pos - 1] |= 1;
128 else
129 dec->data[dec->data_pos++] = 1;
130 db += 64;
131 } else if (mb->macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA) {
132 dec->data[dec->data_pos++] = 1;
133 }
134 }
135 }
136
137 static INLINE void
138 nouveau_vpe_mb_data_blocks(struct nouveau_decoder *dec, const struct pipe_mpeg12_macroblock *mb)
139 {
140 int cbb;
141 unsigned cbp = mb->coded_block_pattern;
142 short *db = mb->blocks;
143 for (cbb = 0x20; cbb > 0; cbb >>= 1) {
144 if (cbb & cbp) {
145 memcpy(&dec->data[dec->data_pos], db, 128);
146 dec->data_pos += 32;
147 db += 64;
148 } else if (mb->macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA) {
149 memset(&dec->data[dec->data_pos], 0, 128);
150 dec->data_pos += 32;
151 }
152 }
153 }
154
155 static INLINE void
156 nouveau_vpe_mb_dct_header(struct nouveau_decoder *dec,
157 const struct pipe_mpeg12_macroblock *mb,
158 bool luma)
159 {
160 unsigned base_dct, cbp;
161 bool intra = mb->macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA;
162 unsigned x = mb->x * 16;
163 unsigned y = luma ? mb->y * 16 : mb->y * 8;
164
165 /* Setup the base dct header */
166 base_dct = dec->current << NV17_MPEG_CMD_CHROMA_MB_HEADER_SURFACE__SHIFT;
167 base_dct |= NV17_MPEG_CMD_CHROMA_MB_HEADER_RUN_SINGLE;
168
169 if (!(mb->x & 1))
170 base_dct |= NV17_MPEG_CMD_CHROMA_MB_HEADER_X_COORD_EVEN;
171 if (intra)
172 cbp = 0x3f;
173 else
174 cbp = mb->coded_block_pattern;
175
176 if (dec->picture_structure == PIPE_MPEG12_PICTURE_STRUCTURE_FRAME) {
177 base_dct |= NV17_MPEG_CMD_CHROMA_MB_HEADER_TYPE_FRAME;
178 if (luma && mb->macroblock_modes.bits.dct_type == PIPE_MPEG12_DCT_TYPE_FIELD)
179 base_dct |= NV17_MPEG_CMD_CHROMA_MB_HEADER_FRAME_DCT_TYPE_FIELD;
180 } else {
181 if (dec->picture_structure == PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_BOTTOM)
182 base_dct |= NV17_MPEG_CMD_CHROMA_MB_HEADER_FIELD_BOTTOM;
183 if (!intra)
184 y *= 2;
185 }
186
187 if (luma) {
188 base_dct |= NV17_MPEG_CMD_LUMA_MB_HEADER_OP_LUMA_MB_HEADER;
189 base_dct |= (cbp >> 2) << NV17_MPEG_CMD_LUMA_MB_HEADER_CBP__SHIFT;
190 } else {
191 base_dct |= NV17_MPEG_CMD_CHROMA_MB_HEADER_OP_CHROMA_MB_HEADER;
192 base_dct |= (cbp & 3) << NV17_MPEG_CMD_CHROMA_MB_HEADER_CBP__SHIFT;
193 }
194 nouveau_vpe_write(dec, base_dct);
195 nouveau_vpe_write(dec, NV17_MPEG_CMD_MB_COORDS_OP_MB_COORDS |
196 x | (y << NV17_MPEG_CMD_MB_COORDS_Y__SHIFT));
197 }
198
199 static INLINE unsigned int
200 nouveau_vpe_mb_mv_flags(bool luma, int mv_h, int mv_v, bool forward, bool first, bool vert)
201 {
202 unsigned mc_header = 0;
203 if (luma)
204 mc_header |= NV17_MPEG_CMD_LUMA_MV_HEADER_OP_LUMA_MV_HEADER;
205 else
206 mc_header |= NV17_MPEG_CMD_CHROMA_MV_HEADER_OP_CHROMA_MV_HEADER;
207 if (mv_h & 1)
208 mc_header |= NV17_MPEG_CMD_CHROMA_MV_HEADER_X_HALF;
209 if (mv_v & 1)
210 mc_header |= NV17_MPEG_CMD_CHROMA_MV_HEADER_Y_HALF;
211 if (!forward)
212 mc_header |= NV17_MPEG_CMD_CHROMA_MV_HEADER_DIRECTION_BACKWARD;
213 if (!first)
214 mc_header |= NV17_MPEG_CMD_CHROMA_MV_HEADER_IDX;
215 if (vert)
216 mc_header |= NV17_MPEG_CMD_LUMA_MV_HEADER_FIELD_BOTTOM;
217 return mc_header;
218 }
219
220 static unsigned pos(int pos, int mov, int max) {
221 int ret = pos + mov;
222 if (pos < 0)
223 return 0;
224 if (pos >= max)
225 return max-1;
226 return ret;
227 }
228
229 /* because we want -1 / 2 = -1 */
230 static int div_down(int val, int mult) {
231 val &= ~(mult - 1);
232 return val / mult;
233 }
234
235 static int div_up(int val, int mult) {
236 val += mult - 1;
237 return val / mult;
238 }
239
240 static INLINE void
241 nouveau_vpe_mb_mv(struct nouveau_decoder *dec, unsigned mc_header,
242 bool luma, bool frame, bool forward, bool vert,
243 int x, int y, const short motions[2],
244 unsigned surface, bool first)
245 {
246 unsigned mc_vector;
247 int mv_horizontal = motions[0];
248 int mv_vertical = motions[1];
249 int mv2 = mc_header & NV17_MPEG_CMD_CHROMA_MV_HEADER_COUNT_2;
250 unsigned width = dec->base.width;
251 unsigned height = dec->base.height;
252 if (mv2)
253 mv_vertical = div_down(mv_vertical, 2);
254 assert(frame); // Untested for non-frames
255 if (!frame)
256 height *= 2;
257
258 mc_header |= surface << NV17_MPEG_CMD_CHROMA_MV_HEADER_SURFACE__SHIFT;
259 if (!luma) {
260 mv_vertical = div_up(mv_vertical, 2);
261 mv_horizontal = div_up(mv_horizontal, 2);
262 height /= 2;
263 }
264 mc_header |= nouveau_vpe_mb_mv_flags(luma, mv_horizontal, mv_vertical, forward, first, vert);
265 nouveau_vpe_write(dec, mc_header);
266
267 mc_vector = NV17_MPEG_CMD_MV_COORDS_OP_MV_COORDS;
268 if (luma)
269 mc_vector |= pos(x, div_down(mv_horizontal, 2), width);
270 else
271 mc_vector |= pos(x, mv_horizontal & ~1, width);
272 if (!mv2)
273 mc_vector |= pos(y, div_down(mv_vertical, 2), height) << NV17_MPEG_CMD_MV_COORDS_Y__SHIFT;
274 else
275 mc_vector |= pos(y, mv_vertical & ~1, height) << NV17_MPEG_CMD_MV_COORDS_Y__SHIFT;
276 nouveau_vpe_write(dec, mc_vector);
277 }
278
279 static void
280 nouveau_vpe_mb_mv_header(struct nouveau_decoder *dec,
281 const struct pipe_mpeg12_macroblock *mb,
282 bool luma)
283 {
284 bool frame = dec->picture_structure == PIPE_MPEG12_PICTURE_STRUCTURE_FRAME;
285 unsigned base;
286 bool forward, backward;
287 int y, y2, x = mb->x * 16;
288 if (luma)
289 y = mb->y * (frame ? 16 : 32);
290 else
291 y = mb->y * (frame ? 8 : 16);
292 if (frame)
293 y2 = y;
294 else
295 y2 = y + (luma ? 16 : 8);
296
297 forward = mb->macroblock_type & PIPE_MPEG12_MB_TYPE_MOTION_FORWARD;
298 backward = mb->macroblock_type & PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD;
299 assert(!forward || dec->past < 8);
300 assert(!backward || dec->future < 8);
301 if (frame) {
302 switch (mb->macroblock_modes.bits.frame_motion_type) {
303 case PIPE_MPEG12_MO_TYPE_FRAME: goto mv1;
304 case PIPE_MPEG12_MO_TYPE_FIELD: goto mv2;
305 case PIPE_MPEG12_MO_TYPE_DUAL_PRIME: {
306 base = NV17_MPEG_CMD_CHROMA_MV_HEADER_COUNT_2;
307 if (forward) {
308 nouveau_vpe_mb_mv(dec, base, luma, frame, TRUE, FALSE,
309 x, y, mb->PMV[0][0], dec->past, TRUE);
310 nouveau_vpe_mb_mv(dec, base, luma, frame, TRUE, TRUE,
311 x, y2, mb->PMV[0][0], dec->past, FALSE);
312 }
313 if (backward && forward) {
314 nouveau_vpe_mb_mv(dec, base, luma, frame, !forward, TRUE,
315 x, y, mb->PMV[1][0], dec->future, TRUE);
316 nouveau_vpe_mb_mv(dec, base, luma, frame, !forward, FALSE,
317 x, y2, mb->PMV[1][1], dec->future, FALSE);
318 } else assert(!backward);
319 break;
320 }
321 default: assert(0);
322 }
323 } else {
324 switch (mb->macroblock_modes.bits.field_motion_type) {
325 case PIPE_MPEG12_MO_TYPE_FIELD: goto mv1;
326 case PIPE_MPEG12_MO_TYPE_16x8: goto mv2;
327 case PIPE_MPEG12_MO_TYPE_DUAL_PRIME: {
328 base = NV17_MPEG_CMD_CHROMA_MV_HEADER_MV_SPLIT_HALF_MB;
329 if (frame)
330 base |= NV17_MPEG_CMD_CHROMA_MV_HEADER_TYPE_FRAME;
331 if (forward)
332 nouveau_vpe_mb_mv(dec, base, luma, frame, TRUE,
333 dec->picture_structure != PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_TOP,
334 x, y, mb->PMV[0][0], dec->past, TRUE);
335 if (backward && forward)
336 nouveau_vpe_mb_mv(dec, base, luma, frame, FALSE,
337 dec->picture_structure == PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_TOP,
338 x, y, mb->PMV[0][1], dec->future, TRUE);
339 else assert(!backward);
340 break;
341 }
342 default: assert(0);
343 }
344 }
345 return;
346
347 mv1:
348 base = NV17_MPEG_CMD_CHROMA_MV_HEADER_MV_SPLIT_HALF_MB;
349 if (frame)
350 base |= NV17_MPEG_CMD_CHROMA_MV_HEADER_TYPE_FRAME;
351 /* frame 16x16 */
352 if (forward)
353 nouveau_vpe_mb_mv(dec, base, luma, frame, TRUE, FALSE,
354 x, y, mb->PMV[0][0], dec->past, TRUE);
355 if (backward)
356 nouveau_vpe_mb_mv(dec, base, luma, frame, !forward, FALSE,
357 x, y, mb->PMV[0][1], dec->future, TRUE);
358 return;
359
360 mv2:
361 base = NV17_MPEG_CMD_CHROMA_MV_HEADER_COUNT_2;
362 if (!frame)
363 base |= NV17_MPEG_CMD_CHROMA_MV_HEADER_MV_SPLIT_HALF_MB;
364 if (forward) {
365 nouveau_vpe_mb_mv(dec, base, luma, frame, TRUE,
366 mb->motion_vertical_field_select & PIPE_MPEG12_FS_FIRST_FORWARD,
367 x, y, mb->PMV[0][0], dec->past, TRUE);
368 nouveau_vpe_mb_mv(dec, base, luma, frame, TRUE,
369 mb->motion_vertical_field_select & PIPE_MPEG12_FS_SECOND_FORWARD,
370 x, y2, mb->PMV[1][0], dec->past, FALSE);
371 }
372 if (backward) {
373 nouveau_vpe_mb_mv(dec, base, luma, frame, !forward,
374 mb->motion_vertical_field_select & PIPE_MPEG12_FS_FIRST_BACKWARD,
375 x, y, mb->PMV[0][1], dec->future, TRUE);
376 nouveau_vpe_mb_mv(dec, base, luma, frame, !forward,
377 mb->motion_vertical_field_select & PIPE_MPEG12_FS_SECOND_BACKWARD,
378 x, y2, mb->PMV[1][1], dec->future, FALSE);
379 }
380 }
381
382 static unsigned
383 nouveau_decoder_surface_index(struct nouveau_decoder *dec,
384 struct pipe_video_buffer *buffer)
385 {
386 struct nouveau_video_buffer *buf = (struct nouveau_video_buffer *)buffer;
387 struct nouveau_channel *chan = dec->screen->channel;
388 struct nouveau_bo *bo_y = ((struct nv04_resource *)buf->resources[0])->bo;
389 struct nouveau_bo *bo_c = ((struct nv04_resource *)buf->resources[1])->bo;
390 unsigned i;
391
392 if (!buf)
393 return 8;
394 for (i = 0; i < dec->num_surfaces; ++i) {
395 if (dec->surfaces[i] == buf)
396 return i;
397 }
398 assert(i < 8);
399 dec->surfaces[i] = buf;
400 dec->num_surfaces++;
401
402 MARK_RING(chan, 3, 2);
403 BEGIN_RING(chan, dec->mpeg, NV31_MPEG_IMAGE_Y_OFFSET(i), 2);
404 OUT_RELOCl(chan, bo_y, 0, NOUVEAU_BO_RDWR);
405 OUT_RELOCl(chan, bo_c, 0, NOUVEAU_BO_RDWR);
406 return i;
407 }
408
409 static void
410 nouveau_decoder_begin_frame(struct pipe_video_decoder *decoder,
411 struct pipe_video_buffer *target,
412 struct pipe_picture_desc *picture)
413 {
414 }
415
416 static void
417 nouveau_decoder_decode_macroblock(struct pipe_video_decoder *decoder,
418 struct pipe_video_buffer *target,
419 struct pipe_picture_desc *picture,
420 const struct pipe_macroblock *pipe_mb,
421 unsigned num_macroblocks)
422 {
423 struct nouveau_decoder *dec = (struct nouveau_decoder *)decoder;
424 struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc*)picture;
425 const struct pipe_mpeg12_macroblock *mb;
426 unsigned i;
427 assert(target->width == decoder->width);
428 assert(target->height == decoder->height);
429
430 dec->current = nouveau_decoder_surface_index(dec, target);
431 assert(dec->current < 8);
432 dec->picture_structure = desc->picture_structure;
433 if (desc->ref[1])
434 dec->future = nouveau_decoder_surface_index(dec, desc->ref[1]);
435 if (desc->ref[0])
436 dec->past = nouveau_decoder_surface_index(dec, desc->ref[0]);
437
438 if (nouveau_vpe_init(dec)) return;
439 mb = (const struct pipe_mpeg12_macroblock *)pipe_mb;
440 for (i = 0; i < num_macroblocks; ++i, mb++) {
441 if (mb->macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA) {
442 nouveau_vpe_mb_dct_header(dec, mb, TRUE);
443 nouveau_vpe_mb_dct_header(dec, mb, FALSE);
444 } else {
445 nouveau_vpe_mb_mv_header(dec, mb, TRUE);
446 nouveau_vpe_mb_dct_header(dec, mb, TRUE);
447
448 nouveau_vpe_mb_mv_header(dec, mb, FALSE);
449 nouveau_vpe_mb_dct_header(dec, mb, FALSE);
450 }
451 if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
452 nouveau_vpe_mb_dct_blocks(dec, mb);
453 else
454 nouveau_vpe_mb_data_blocks(dec, mb);
455 }
456 }
457
458 static void
459 nouveau_decoder_end_frame(struct pipe_video_decoder *decoder,
460 struct pipe_video_buffer *target,
461 struct pipe_picture_desc *picture)
462 {
463 }
464
465 static void
466 nouveau_decoder_flush(struct pipe_video_decoder *decoder)
467 {
468 struct nouveau_decoder *dec = (struct nouveau_decoder *)decoder;
469 if (dec->ofs)
470 nouveau_vpe_fini(dec);
471 }
472
473 static void
474 nouveau_decoder_destroy(struct pipe_video_decoder *decoder)
475 {
476 struct nouveau_decoder *dec = (struct nouveau_decoder*)decoder;
477
478 if (dec->cmds) {
479 nouveau_bo_unmap(dec->data_bo);
480 nouveau_bo_unmap(dec->cmd_bo);
481 }
482
483 if (dec->data_bo)
484 nouveau_bo_ref(NULL, &dec->data_bo);
485 if (dec->cmd_bo)
486 nouveau_bo_ref(NULL, &dec->cmd_bo);
487 if (dec->fence_bo)
488 nouveau_bo_ref(NULL, &dec->fence_bo);
489 nouveau_grobj_free(&dec->mpeg);
490 FREE(dec);
491 }
492
493 static struct pipe_video_decoder *
494 nouveau_create_decoder(struct pipe_context *context,
495 struct nouveau_screen *screen,
496 enum pipe_video_profile profile,
497 enum pipe_video_entrypoint entrypoint,
498 enum pipe_video_chroma_format chroma_format,
499 unsigned width, unsigned height,
500 unsigned max_references, bool expect_chunked_decode)
501 {
502 struct nouveau_channel *chan = screen->channel;
503 struct nouveau_grobj *mpeg = NULL;
504 struct nouveau_decoder *dec;
505 int ret;
506 bool is8274 = screen->device->chipset > 0x80;
507
508 debug_printf("Acceleration level: %s\n", entrypoint <= PIPE_VIDEO_ENTRYPOINT_BITSTREAM ? "bit":
509 entrypoint == PIPE_VIDEO_ENTRYPOINT_IDCT ? "IDCT" : "MC");
510
511 if (getenv("XVMC_VL"))
512 goto vl;
513 if (u_reduce_video_profile(profile) != PIPE_VIDEO_CODEC_MPEG12)
514 goto vl;
515 if (screen->device->chipset >= 0x98 && screen->device->chipset != 0xa0)
516 goto vl;
517
518 width = align(width, 64);
519 height = align(height, 64);
520
521 if (is8274)
522 ret = nouveau_grobj_alloc(chan, 0xbeef8274, 0x8274, &mpeg);
523 else
524 ret = nouveau_grobj_alloc(chan, 0xbeef8274, 0x3174, &mpeg);
525 if (ret < 0) {
526 debug_printf("Creation failed: %s (%i)\n", strerror(-ret), ret);
527 return NULL;
528 }
529
530 dec = CALLOC_STRUCT(nouveau_decoder);
531 if (!dec) {
532 nouveau_grobj_free(&mpeg);
533 goto fail;
534 }
535 dec->mpeg = mpeg;
536 dec->base.context = context;
537 dec->base.profile = profile;
538 dec->base.entrypoint = entrypoint;
539 dec->base.chroma_format = chroma_format;
540 dec->base.width = width;
541 dec->base.height = height;
542 dec->base.max_references = max_references;
543 dec->base.destroy = nouveau_decoder_destroy;
544 dec->base.begin_frame = nouveau_decoder_begin_frame;
545 dec->base.decode_macroblock = nouveau_decoder_decode_macroblock;
546 dec->base.begin_frame = nouveau_decoder_end_frame;
547 dec->base.flush = nouveau_decoder_flush;
548 dec->screen = screen;
549
550 ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART, 0, 1024 * 1024, &dec->cmd_bo);
551 if (ret)
552 goto fail;
553
554 ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART, 0, width * height * 6, &dec->data_bo);
555 if (ret)
556 goto fail;
557
558 ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART|NOUVEAU_BO_MAP, 0, 4096,
559 &dec->fence_bo);
560 if (ret)
561 goto fail;
562 nouveau_bo_map(dec->fence_bo, NOUVEAU_BO_RDWR);
563 dec->fence_map = dec->fence_bo->map;
564 nouveau_bo_unmap(dec->fence_bo);
565 dec->fence_map[0] = 0;
566
567 if (is8274)
568 MARK_RING(chan, 25, 3);
569 else
570 MARK_RING(chan, 20, 2);
571
572 BEGIN_RING(chan, mpeg, NV31_MPEG_DMA_CMD, 1);
573 OUT_RING(chan, chan->vram->handle);
574
575 BEGIN_RING(chan, mpeg, NV31_MPEG_DMA_DATA, 1);
576 OUT_RING(chan, chan->vram->handle);
577
578 BEGIN_RING(chan, mpeg, NV31_MPEG_DMA_IMAGE, 1);
579 OUT_RING(chan, chan->vram->handle);
580
581 BEGIN_RING(chan, mpeg, NV31_MPEG_PITCH, 2);
582 OUT_RING(chan, width | NV31_MPEG_PITCH_UNK);
583 OUT_RING(chan, (height << NV31_MPEG_SIZE_H__SHIFT) | width);
584
585 BEGIN_RING(chan, mpeg, NV31_MPEG_FORMAT, 2);
586 OUT_RING(chan, 0);
587 switch (entrypoint) {
588 case PIPE_VIDEO_ENTRYPOINT_BITSTREAM: OUT_RING(chan, 0x100); break;
589 case PIPE_VIDEO_ENTRYPOINT_IDCT: OUT_RING(chan, 1); break;
590 case PIPE_VIDEO_ENTRYPOINT_MC: OUT_RING(chan, 0); break;
591 default: assert(0);
592 }
593
594 if (is8274) {
595 BEGIN_RING(chan, mpeg, NV84_MPEG_DMA_QUERY, 1);
596 OUT_RING(chan, chan->vram->handle);
597
598 BEGIN_RING(chan, mpeg, NV84_MPEG_QUERY_OFFSET, 2);
599 OUT_RELOCl(chan, dec->fence_bo, 0, NOUVEAU_BO_WR|NOUVEAU_BO_GART);
600 OUT_RING(chan, dec->fence_seq);
601 }
602
603 ret = nouveau_vpe_init(dec);
604 if (ret)
605 goto fail;
606 nouveau_vpe_fini(dec);
607 return &dec->base;
608
609 fail:
610 nouveau_decoder_destroy(&dec->base);
611 return NULL;
612
613 vl:
614 debug_printf("Using g3dvl renderer\n");
615 return vl_create_decoder(context, profile, entrypoint,
616 chroma_format, width, height,
617 max_references, expect_chunked_decode);
618 }
619
620 static struct pipe_sampler_view **
621 nouveau_video_buffer_sampler_view_planes(struct pipe_video_buffer *buffer)
622 {
623 struct nouveau_video_buffer *buf = (struct nouveau_video_buffer *)buffer;
624 struct pipe_sampler_view sv_templ;
625 struct pipe_context *pipe;
626 unsigned i;
627
628 assert(buf);
629
630 pipe = buf->base.context;
631
632 for (i = 0; i < buf->num_planes; ++i ) {
633 if (!buf->sampler_view_planes[i]) {
634 memset(&sv_templ, 0, sizeof(sv_templ));
635 u_sampler_view_default_template(&sv_templ, buf->resources[i], buf->resources[i]->format);
636
637 if (util_format_get_nr_components(buf->resources[i]->format) == 1)
638 sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = sv_templ.swizzle_a = PIPE_SWIZZLE_RED;
639
640 buf->sampler_view_planes[i] = pipe->create_sampler_view(pipe, buf->resources[i], &sv_templ);
641 if (!buf->sampler_view_planes[i])
642 goto error;
643 }
644 }
645
646 return buf->sampler_view_planes;
647
648 error:
649 for (i = 0; i < buf->num_planes; ++i )
650 pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL);
651
652 return NULL;
653 }
654
655 static struct pipe_sampler_view **
656 nouveau_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer)
657 {
658 struct nouveau_video_buffer *buf = (struct nouveau_video_buffer *)buffer;
659 struct pipe_sampler_view sv_templ;
660 struct pipe_context *pipe;
661 unsigned i, j, component;
662
663 assert(buf);
664
665 pipe = buf->base.context;
666
667 for (component = 0, i = 0; i < buf->num_planes; ++i ) {
668 unsigned nr_components = util_format_get_nr_components(buf->resources[i]->format);
669
670 for (j = 0; j < nr_components; ++j, ++component) {
671 assert(component < VL_NUM_COMPONENTS);
672
673 if (!buf->sampler_view_components[component]) {
674 memset(&sv_templ, 0, sizeof(sv_templ));
675 u_sampler_view_default_template(&sv_templ, buf->resources[i], buf->resources[i]->format);
676 sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = PIPE_SWIZZLE_RED + j;
677 sv_templ.swizzle_a = PIPE_SWIZZLE_ONE;
678 buf->sampler_view_components[component] = pipe->create_sampler_view(pipe, buf->resources[i], &sv_templ);
679 if (!buf->sampler_view_components[component])
680 goto error;
681 }
682 }
683 }
684
685 return buf->sampler_view_components;
686
687 error:
688 for (i = 0; i < 3; ++i )
689 pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL);
690
691 return NULL;
692 }
693
694 static struct pipe_surface **
695 nouveau_video_buffer_surfaces(struct pipe_video_buffer *buffer)
696 {
697 struct nouveau_video_buffer *buf = (struct nouveau_video_buffer *)buffer;
698 struct pipe_surface surf_templ;
699 struct pipe_context *pipe;
700 unsigned i;
701
702 assert(buf);
703
704 pipe = buf->base.context;
705
706 for (i = 0; i < buf->num_planes; ++i ) {
707 if (!buf->surfaces[i]) {
708 memset(&surf_templ, 0, sizeof(surf_templ));
709 surf_templ.format = buf->resources[i]->format;
710 surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
711 buf->surfaces[i] = pipe->create_surface(pipe, buf->resources[i], &surf_templ);
712 if (!buf->surfaces[i])
713 goto error;
714 }
715 }
716
717 return buf->surfaces;
718
719 error:
720 for (i = 0; i < buf->num_planes; ++i )
721 pipe_surface_reference(&buf->surfaces[i], NULL);
722
723 return NULL;
724 }
725
726 static void
727 nouveau_video_buffer_destroy(struct pipe_video_buffer *buffer)
728 {
729 struct nouveau_video_buffer *buf = (struct nouveau_video_buffer *)buffer;
730 unsigned i;
731
732 assert(buf);
733
734 for (i = 0; i < buf->num_planes; ++i) {
735 pipe_surface_reference(&buf->surfaces[i], NULL);
736 pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL);
737 pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL);
738 pipe_resource_reference(&buf->resources[i], NULL);
739 }
740 for (;i < 3;++i)
741 pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL);
742
743 FREE(buffer);
744 }
745
746 static struct pipe_video_buffer *
747 nouveau_video_buffer_create(struct pipe_context *pipe,
748 struct nouveau_screen *screen,
749 const struct pipe_video_buffer *templat)
750 {
751 struct nouveau_video_buffer *buffer;
752 struct pipe_resource templ;
753 unsigned width, height;
754
755 /* Only do a linear surface when a hardware decoder is used
756 * hardware decoder is only supported on some chipsets
757 * and it only supports the NV12 format
758 */
759 if (templat->buffer_format != PIPE_FORMAT_NV12 || getenv("XVMC_VL") ||
760 (screen->device->chipset >= 0x98 && screen->device->chipset != 0xa0))
761 return vl_video_buffer_create(pipe, templat);
762
763 assert(templat->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
764 width = align(templat->width, 64);
765 height = align(templat->height, 64);
766
767 buffer = CALLOC_STRUCT(nouveau_video_buffer);
768 if (!buffer)
769 return NULL;
770
771 buffer->base.context = pipe;
772 buffer->base.destroy = nouveau_video_buffer_destroy;
773 buffer->base.get_sampler_view_planes = nouveau_video_buffer_sampler_view_planes;
774 buffer->base.get_sampler_view_components = nouveau_video_buffer_sampler_view_components;
775 buffer->base.get_surfaces = nouveau_video_buffer_surfaces;
776 buffer->base.chroma_format = templat->chroma_format;
777 buffer->base.width = width;
778 buffer->base.height = height;
779 buffer->num_planes = 2;
780
781 memset(&templ, 0, sizeof(templ));
782 templ.target = PIPE_TEXTURE_2D;
783 templ.format = PIPE_FORMAT_R8_UNORM;
784 templ.width0 = width;
785 templ.height0 = height;
786 templ.depth0 = 1;
787 templ.array_size = 1;
788 templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
789 templ.usage = PIPE_USAGE_STATIC;
790 templ.flags = NOUVEAU_RESOURCE_FLAG_LINEAR;
791
792 buffer->resources[0] = pipe->screen->resource_create(pipe->screen, &templ);
793 if (!buffer->resources[0])
794 goto error;
795 templ.width0 /= 2;
796 templ.height0 /= 2;
797 templ.format = PIPE_FORMAT_R8G8_UNORM;
798 buffer->resources[1] = pipe->screen->resource_create(pipe->screen, &templ);
799 if (!buffer->resources[1])
800 goto error;
801 return &buffer->base;
802
803 error:
804 nouveau_video_buffer_destroy(&buffer->base);
805 return NULL;
806 }
807
808 static int
809 nouveau_screen_get_video_param(struct pipe_screen *pscreen,
810 enum pipe_video_profile profile,
811 enum pipe_video_cap param)
812 {
813 switch (param) {
814 case PIPE_VIDEO_CAP_SUPPORTED:
815 return vl_profile_supported(pscreen, profile);
816 case PIPE_VIDEO_CAP_NPOT_TEXTURES:
817 return 1;
818 case PIPE_VIDEO_CAP_MAX_WIDTH:
819 case PIPE_VIDEO_CAP_MAX_HEIGHT:
820 return vl_video_buffer_max_size(pscreen);
821 case PIPE_VIDEO_CAP_PREFERED_FORMAT:
822 return PIPE_FORMAT_NV12;
823 case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
824 return false;
825 case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
826 return false;
827 case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
828 return true;
829 default:
830 debug_printf("unknown video param: %d\n", param);
831 return 0;
832 }
833 }
834
835 void
836 nouveau_screen_init_vdec(struct nouveau_screen *screen)
837 {
838 screen->base.get_video_param = nouveau_screen_get_video_param;
839 screen->base.is_video_format_supported = vl_video_buffer_is_format_supported;
840 }
841
842 static struct pipe_video_decoder *
843 nouveau_context_create_decoder(struct pipe_context *context,
844 enum pipe_video_profile profile,
845 enum pipe_video_entrypoint entrypoint,
846 enum pipe_video_chroma_format chroma_format,
847 unsigned width, unsigned height,
848 unsigned max_references, bool expect_chunked_decode)
849 {
850 struct nouveau_screen *screen = nouveau_context(context)->screen;
851 return nouveau_create_decoder(context, screen, profile, entrypoint,
852 chroma_format, width, height,
853 max_references, expect_chunked_decode);
854 }
855
856 static struct pipe_video_buffer *
857 nouveau_context_video_buffer_create(struct pipe_context *pipe,
858 const struct pipe_video_buffer *templat)
859 {
860 struct nouveau_screen *screen = nouveau_context(pipe)->screen;
861 return nouveau_video_buffer_create(pipe, screen, templat);
862 }
863
864 void
865 nouveau_context_init_vdec(struct nouveau_context *nv)
866 {
867 nv->pipe.create_video_decoder = nouveau_context_create_decoder;
868 nv->pipe.create_video_buffer = nouveau_context_video_buffer_create;
869 }