2 * Copyright 2011 Maarten Lankhorst
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 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.
23 #include "vl/vl_decoder.h"
24 #include "vl/vl_video_buffer.h"
26 #include "nouveau_screen.h"
27 #include "nouveau_context.h"
28 #include "nouveau_video.h"
30 #include "nouveau/nouveau_buffer.h"
31 #include "util/u_video.h"
32 #include "util/u_format.h"
33 #include "util/u_sampler.h"
36 nouveau_vpe_init(struct nouveau_decoder
*dec
) {
40 ret
= nouveau_bo_map(dec
->cmd_bo
, NOUVEAU_BO_RDWR
, dec
->client
);
42 debug_printf("Mapping cmd bo: %s\n", strerror(-ret
));
45 ret
= nouveau_bo_map(dec
->data_bo
, NOUVEAU_BO_RDWR
, dec
->client
);
47 debug_printf("Mapping data bo: %s\n", strerror(-ret
));
50 dec
->cmds
= dec
->cmd_bo
->map
;
51 dec
->data
= dec
->data_bo
->map
;
56 nouveau_vpe_synch(struct nouveau_decoder
*dec
) {
57 struct nouveau_pushbuf
*push
= dec
->push
;
60 BEGIN_NV04(push
, NV84_MPEG(QUERY_COUNTER
), 1);
61 PUSH_DATA (push
, ++dec
->fence_seq
);
63 while (dec
->fence_map
[0] != dec
->fence_seq
)
71 nouveau_vpe_fini(struct nouveau_decoder
*dec
) {
72 struct nouveau_pushbuf
*push
= dec
->push
;
76 nouveau_pushbuf_space(push
, 8, 2, 0);
77 nouveau_bufctx_reset(dec
->bufctx
, NV31_VIDEO_BIND_CMD
);
79 #define BCTX_ARGS dec->bufctx, NV31_VIDEO_BIND_CMD, NOUVEAU_BO_RD
81 BEGIN_NV04(push
, NV31_MPEG(CMD_OFFSET
), 2);
82 PUSH_MTHDl(push
, NV31_MPEG(CMD_OFFSET
), dec
->cmd_bo
, 0, BCTX_ARGS
);
83 PUSH_DATA (push
, dec
->ofs
* 4);
85 BEGIN_NV04(push
, NV31_MPEG(DATA_OFFSET
), 2);
86 PUSH_MTHDl(push
, NV31_MPEG(DATA_OFFSET
), dec
->data_bo
, 0, BCTX_ARGS
);
87 PUSH_DATA (push
, dec
->data_pos
* 4);
91 if (unlikely(nouveau_pushbuf_validate(dec
->push
)))
94 BEGIN_NV04(push
, NV31_MPEG(EXEC
), 1);
97 nouveau_vpe_synch(dec
);
98 dec
->ofs
= dec
->data_pos
= dec
->num_surfaces
= 0;
99 dec
->cmds
= dec
->data
= NULL
;
100 dec
->current
= dec
->future
= dec
->past
= 8;
104 nouveau_vpe_mb_dct_blocks(struct nouveau_decoder
*dec
, const struct pipe_mpeg12_macroblock
*mb
)
107 unsigned cbp
= mb
->coded_block_pattern
;
108 short *db
= mb
->blocks
;
109 for (cbb
= 0x20; cbb
> 0; cbb
>>= 1) {
112 for (i
= 0; i
< 64; ++i
) {
113 if (!db
[i
]) continue;
114 dec
->data
[dec
->data_pos
++] = (db
[i
] << 16) | (i
* 2);
118 dec
->data
[dec
->data_pos
- 1] |= 1;
120 dec
->data
[dec
->data_pos
++] = 1;
122 } else if (mb
->macroblock_type
& PIPE_MPEG12_MB_TYPE_INTRA
) {
123 dec
->data
[dec
->data_pos
++] = 1;
129 nouveau_vpe_mb_data_blocks(struct nouveau_decoder
*dec
, const struct pipe_mpeg12_macroblock
*mb
)
132 unsigned cbp
= mb
->coded_block_pattern
;
133 short *db
= mb
->blocks
;
134 for (cbb
= 0x20; cbb
> 0; cbb
>>= 1) {
136 memcpy(&dec
->data
[dec
->data_pos
], db
, 128);
139 } else if (mb
->macroblock_type
& PIPE_MPEG12_MB_TYPE_INTRA
) {
140 memset(&dec
->data
[dec
->data_pos
], 0, 128);
147 nouveau_vpe_mb_dct_header(struct nouveau_decoder
*dec
,
148 const struct pipe_mpeg12_macroblock
*mb
,
151 unsigned base_dct
, cbp
;
152 bool intra
= mb
->macroblock_type
& PIPE_MPEG12_MB_TYPE_INTRA
;
153 unsigned x
= mb
->x
* 16;
154 unsigned y
= luma
? mb
->y
* 16 : mb
->y
* 8;
156 /* Setup the base dct header */
157 base_dct
= dec
->current
<< NV17_MPEG_CMD_CHROMA_MB_HEADER_SURFACE__SHIFT
;
158 base_dct
|= NV17_MPEG_CMD_CHROMA_MB_HEADER_RUN_SINGLE
;
161 base_dct
|= NV17_MPEG_CMD_CHROMA_MB_HEADER_X_COORD_EVEN
;
165 cbp
= mb
->coded_block_pattern
;
167 if (dec
->picture_structure
== PIPE_MPEG12_PICTURE_STRUCTURE_FRAME
) {
168 base_dct
|= NV17_MPEG_CMD_CHROMA_MB_HEADER_TYPE_FRAME
;
169 if (luma
&& mb
->macroblock_modes
.bits
.dct_type
== PIPE_MPEG12_DCT_TYPE_FIELD
)
170 base_dct
|= NV17_MPEG_CMD_CHROMA_MB_HEADER_FRAME_DCT_TYPE_FIELD
;
172 if (dec
->picture_structure
== PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_BOTTOM
)
173 base_dct
|= NV17_MPEG_CMD_CHROMA_MB_HEADER_FIELD_BOTTOM
;
179 base_dct
|= NV17_MPEG_CMD_LUMA_MB_HEADER_OP_LUMA_MB_HEADER
;
180 base_dct
|= (cbp
>> 2) << NV17_MPEG_CMD_LUMA_MB_HEADER_CBP__SHIFT
;
182 base_dct
|= NV17_MPEG_CMD_CHROMA_MB_HEADER_OP_CHROMA_MB_HEADER
;
183 base_dct
|= (cbp
& 3) << NV17_MPEG_CMD_CHROMA_MB_HEADER_CBP__SHIFT
;
185 nouveau_vpe_write(dec
, base_dct
);
186 nouveau_vpe_write(dec
, NV17_MPEG_CMD_MB_COORDS_OP_MB_COORDS
|
187 x
| (y
<< NV17_MPEG_CMD_MB_COORDS_Y__SHIFT
));
190 static INLINE
unsigned int
191 nouveau_vpe_mb_mv_flags(bool luma
, int mv_h
, int mv_v
, bool forward
, bool first
, bool vert
)
193 unsigned mc_header
= 0;
195 mc_header
|= NV17_MPEG_CMD_LUMA_MV_HEADER_OP_LUMA_MV_HEADER
;
197 mc_header
|= NV17_MPEG_CMD_CHROMA_MV_HEADER_OP_CHROMA_MV_HEADER
;
199 mc_header
|= NV17_MPEG_CMD_CHROMA_MV_HEADER_X_HALF
;
201 mc_header
|= NV17_MPEG_CMD_CHROMA_MV_HEADER_Y_HALF
;
203 mc_header
|= NV17_MPEG_CMD_CHROMA_MV_HEADER_DIRECTION_BACKWARD
;
205 mc_header
|= NV17_MPEG_CMD_CHROMA_MV_HEADER_IDX
;
207 mc_header
|= NV17_MPEG_CMD_LUMA_MV_HEADER_FIELD_BOTTOM
;
211 static unsigned pos(int pos
, int mov
, int max
) {
220 /* because we want -1 / 2 = -1 */
221 static int div_down(int val
, int mult
) {
226 static int div_up(int val
, int mult
) {
232 nouveau_vpe_mb_mv(struct nouveau_decoder
*dec
, unsigned mc_header
,
233 bool luma
, bool frame
, bool forward
, bool vert
,
234 int x
, int y
, const short motions
[2],
235 unsigned surface
, bool first
)
238 int mv_horizontal
= motions
[0];
239 int mv_vertical
= motions
[1];
240 int mv2
= mc_header
& NV17_MPEG_CMD_CHROMA_MV_HEADER_COUNT_2
;
241 unsigned width
= dec
->base
.width
;
242 unsigned height
= dec
->base
.height
;
244 mv_vertical
= div_down(mv_vertical
, 2);
245 assert(frame
); // Untested for non-frames
249 mc_header
|= surface
<< NV17_MPEG_CMD_CHROMA_MV_HEADER_SURFACE__SHIFT
;
251 mv_vertical
= div_up(mv_vertical
, 2);
252 mv_horizontal
= div_up(mv_horizontal
, 2);
255 mc_header
|= nouveau_vpe_mb_mv_flags(luma
, mv_horizontal
, mv_vertical
, forward
, first
, vert
);
256 nouveau_vpe_write(dec
, mc_header
);
258 mc_vector
= NV17_MPEG_CMD_MV_COORDS_OP_MV_COORDS
;
260 mc_vector
|= pos(x
, div_down(mv_horizontal
, 2), width
);
262 mc_vector
|= pos(x
, mv_horizontal
& ~1, width
);
264 mc_vector
|= pos(y
, div_down(mv_vertical
, 2), height
) << NV17_MPEG_CMD_MV_COORDS_Y__SHIFT
;
266 mc_vector
|= pos(y
, mv_vertical
& ~1, height
) << NV17_MPEG_CMD_MV_COORDS_Y__SHIFT
;
267 nouveau_vpe_write(dec
, mc_vector
);
271 nouveau_vpe_mb_mv_header(struct nouveau_decoder
*dec
,
272 const struct pipe_mpeg12_macroblock
*mb
,
275 bool frame
= dec
->picture_structure
== PIPE_MPEG12_PICTURE_STRUCTURE_FRAME
;
277 bool forward
, backward
;
278 int y
, y2
, x
= mb
->x
* 16;
280 y
= mb
->y
* (frame
? 16 : 32);
282 y
= mb
->y
* (frame
? 8 : 16);
286 y2
= y
+ (luma
? 16 : 8);
288 forward
= mb
->macroblock_type
& PIPE_MPEG12_MB_TYPE_MOTION_FORWARD
;
289 backward
= mb
->macroblock_type
& PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD
;
290 assert(!forward
|| dec
->past
< 8);
291 assert(!backward
|| dec
->future
< 8);
293 switch (mb
->macroblock_modes
.bits
.frame_motion_type
) {
294 case PIPE_MPEG12_MO_TYPE_FRAME
: goto mv1
;
295 case PIPE_MPEG12_MO_TYPE_FIELD
: goto mv2
;
296 case PIPE_MPEG12_MO_TYPE_DUAL_PRIME
: {
297 base
= NV17_MPEG_CMD_CHROMA_MV_HEADER_COUNT_2
;
299 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, TRUE
, FALSE
,
300 x
, y
, mb
->PMV
[0][0], dec
->past
, TRUE
);
301 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, TRUE
, TRUE
,
302 x
, y2
, mb
->PMV
[0][0], dec
->past
, FALSE
);
304 if (backward
&& forward
) {
305 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, !forward
, TRUE
,
306 x
, y
, mb
->PMV
[1][0], dec
->future
, TRUE
);
307 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, !forward
, FALSE
,
308 x
, y2
, mb
->PMV
[1][1], dec
->future
, FALSE
);
309 } else assert(!backward
);
315 switch (mb
->macroblock_modes
.bits
.field_motion_type
) {
316 case PIPE_MPEG12_MO_TYPE_FIELD
: goto mv1
;
317 case PIPE_MPEG12_MO_TYPE_16x8
: goto mv2
;
318 case PIPE_MPEG12_MO_TYPE_DUAL_PRIME
: {
319 base
= NV17_MPEG_CMD_CHROMA_MV_HEADER_MV_SPLIT_HALF_MB
;
321 base
|= NV17_MPEG_CMD_CHROMA_MV_HEADER_TYPE_FRAME
;
323 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, TRUE
,
324 dec
->picture_structure
!= PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_TOP
,
325 x
, y
, mb
->PMV
[0][0], dec
->past
, TRUE
);
326 if (backward
&& forward
)
327 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, FALSE
,
328 dec
->picture_structure
== PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_TOP
,
329 x
, y
, mb
->PMV
[0][1], dec
->future
, TRUE
);
330 else assert(!backward
);
339 base
= NV17_MPEG_CMD_CHROMA_MV_HEADER_MV_SPLIT_HALF_MB
;
341 base
|= NV17_MPEG_CMD_CHROMA_MV_HEADER_TYPE_FRAME
;
344 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, TRUE
, FALSE
,
345 x
, y
, mb
->PMV
[0][0], dec
->past
, TRUE
);
347 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, !forward
, FALSE
,
348 x
, y
, mb
->PMV
[0][1], dec
->future
, TRUE
);
352 base
= NV17_MPEG_CMD_CHROMA_MV_HEADER_COUNT_2
;
354 base
|= NV17_MPEG_CMD_CHROMA_MV_HEADER_MV_SPLIT_HALF_MB
;
356 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, TRUE
,
357 mb
->motion_vertical_field_select
& PIPE_MPEG12_FS_FIRST_FORWARD
,
358 x
, y
, mb
->PMV
[0][0], dec
->past
, TRUE
);
359 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, TRUE
,
360 mb
->motion_vertical_field_select
& PIPE_MPEG12_FS_SECOND_FORWARD
,
361 x
, y2
, mb
->PMV
[1][0], dec
->past
, FALSE
);
364 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, !forward
,
365 mb
->motion_vertical_field_select
& PIPE_MPEG12_FS_FIRST_BACKWARD
,
366 x
, y
, mb
->PMV
[0][1], dec
->future
, TRUE
);
367 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, !forward
,
368 mb
->motion_vertical_field_select
& PIPE_MPEG12_FS_SECOND_BACKWARD
,
369 x
, y2
, mb
->PMV
[1][1], dec
->future
, FALSE
);
374 nouveau_decoder_surface_index(struct nouveau_decoder
*dec
,
375 struct pipe_video_buffer
*buffer
)
377 struct nouveau_video_buffer
*buf
= (struct nouveau_video_buffer
*)buffer
;
378 struct nouveau_pushbuf
*push
= dec
->push
;
379 struct nouveau_bo
*bo_y
= nv04_resource(buf
->resources
[0])->bo
;
380 struct nouveau_bo
*bo_c
= nv04_resource(buf
->resources
[1])->bo
;
386 for (i
= 0; i
< dec
->num_surfaces
; ++i
) {
387 if (dec
->surfaces
[i
] == buf
)
391 dec
->surfaces
[i
] = buf
;
394 nouveau_bufctx_reset(dec
->bufctx
, NV31_VIDEO_BIND_IMG(i
));
396 #define BCTX_ARGS dec->bufctx, NV31_VIDEO_BIND_IMG(i), NOUVEAU_BO_RDWR
397 BEGIN_NV04(push
, NV31_MPEG(IMAGE_Y_OFFSET(i
)), 2);
398 PUSH_MTHDl(push
, NV31_MPEG(IMAGE_Y_OFFSET(i
)), bo_y
, 0, BCTX_ARGS
);
399 PUSH_MTHDl(push
, NV31_MPEG(IMAGE_C_OFFSET(i
)), bo_c
, 0, BCTX_ARGS
);
406 nouveau_decoder_begin_frame(struct pipe_video_codec
*decoder
,
407 struct pipe_video_buffer
*target
,
408 struct pipe_picture_desc
*picture
)
413 nouveau_decoder_decode_macroblock(struct pipe_video_codec
*decoder
,
414 struct pipe_video_buffer
*target
,
415 struct pipe_picture_desc
*picture
,
416 const struct pipe_macroblock
*pipe_mb
,
417 unsigned num_macroblocks
)
419 struct nouveau_decoder
*dec
= (struct nouveau_decoder
*)decoder
;
420 struct pipe_mpeg12_picture_desc
*desc
= (struct pipe_mpeg12_picture_desc
*)picture
;
421 const struct pipe_mpeg12_macroblock
*mb
;
423 assert(target
->width
== decoder
->width
);
424 assert(target
->height
== decoder
->height
);
426 dec
->current
= nouveau_decoder_surface_index(dec
, target
);
427 assert(dec
->current
< 8);
428 dec
->picture_structure
= desc
->picture_structure
;
430 dec
->future
= nouveau_decoder_surface_index(dec
, desc
->ref
[1]);
432 dec
->past
= nouveau_decoder_surface_index(dec
, desc
->ref
[0]);
434 if (nouveau_vpe_init(dec
)) return;
436 /* initialize scan order */
437 nouveau_vpe_write(dec
, 0x720000c0);
438 nouveau_vpe_write(dec
, dec
->data_pos
);
440 mb
= (const struct pipe_mpeg12_macroblock
*)pipe_mb
;
441 for (i
= 0; i
< num_macroblocks
; ++i
, mb
++) {
442 if (mb
->macroblock_type
& PIPE_MPEG12_MB_TYPE_INTRA
) {
443 nouveau_vpe_mb_dct_header(dec
, mb
, TRUE
);
444 nouveau_vpe_mb_dct_header(dec
, mb
, FALSE
);
446 nouveau_vpe_mb_mv_header(dec
, mb
, TRUE
);
447 nouveau_vpe_mb_dct_header(dec
, mb
, TRUE
);
449 nouveau_vpe_mb_mv_header(dec
, mb
, FALSE
);
450 nouveau_vpe_mb_dct_header(dec
, mb
, FALSE
);
452 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
453 nouveau_vpe_mb_dct_blocks(dec
, mb
);
455 nouveau_vpe_mb_data_blocks(dec
, mb
);
460 nouveau_decoder_end_frame(struct pipe_video_codec
*decoder
,
461 struct pipe_video_buffer
*target
,
462 struct pipe_picture_desc
*picture
)
467 nouveau_decoder_flush(struct pipe_video_codec
*decoder
)
469 struct nouveau_decoder
*dec
= (struct nouveau_decoder
*)decoder
;
471 nouveau_vpe_fini(dec
);
475 nouveau_decoder_destroy(struct pipe_video_codec
*decoder
)
477 struct nouveau_decoder
*dec
= (struct nouveau_decoder
*)decoder
;
480 nouveau_bo_ref(NULL
, &dec
->data_bo
);
482 nouveau_bo_ref(NULL
, &dec
->cmd_bo
);
484 nouveau_bo_ref(NULL
, &dec
->fence_bo
);
486 nouveau_object_del(&dec
->mpeg
);
489 nouveau_bufctx_del(&dec
->bufctx
);
491 nouveau_pushbuf_del(&dec
->push
);
493 nouveau_client_del(&dec
->client
);
495 nouveau_object_del(&dec
->chan
);
500 static struct pipe_video_codec
*
501 nouveau_create_decoder(struct pipe_context
*context
,
502 const struct pipe_video_codec
*templ
,
503 struct nouveau_screen
*screen
)
505 struct nv04_fifo nv04_data
= { .vram
= 0xbeef0201, .gart
= 0xbeef0202 };
506 unsigned width
= templ
->width
, height
= templ
->height
;
507 struct nouveau_object
*mpeg
= NULL
;
508 struct nouveau_decoder
*dec
;
509 struct nouveau_pushbuf
*push
;
511 bool is8274
= screen
->device
->chipset
> 0x80;
513 debug_printf("Acceleration level: %s\n", templ
->entrypoint
<= PIPE_VIDEO_ENTRYPOINT_BITSTREAM
? "bit":
514 templ
->entrypoint
== PIPE_VIDEO_ENTRYPOINT_IDCT
? "IDCT" : "MC");
516 if (getenv("XVMC_VL"))
518 if (u_reduce_video_profile(templ
->profile
) != PIPE_VIDEO_FORMAT_MPEG12
)
520 if (screen
->device
->chipset
>= 0x98 && screen
->device
->chipset
!= 0xa0)
522 if (screen
->device
->chipset
< 0x31 || screen
->device
->chipset
== 0x35)
525 dec
= CALLOC_STRUCT(nouveau_decoder
);
529 ret
= nouveau_object_new(&screen
->device
->object
, 0,
530 NOUVEAU_FIFO_CHANNEL_CLASS
,
531 &nv04_data
, sizeof(nv04_data
), &dec
->chan
);
534 ret
= nouveau_client_new(screen
->device
, &dec
->client
);
537 ret
= nouveau_pushbuf_new(dec
->client
, dec
->chan
, 2, 4096, 1, &dec
->push
);
540 ret
= nouveau_bufctx_new(dec
->client
, NV31_VIDEO_BIND_COUNT
, &dec
->bufctx
);
545 width
= align(width
, 64);
546 height
= align(height
, 64);
549 ret
= nouveau_object_new(dec
->chan
, 0xbeef8274, NV84_MPEG_CLASS
, NULL
, 0,
552 ret
= nouveau_object_new(dec
->chan
, 0xbeef3174, NV31_MPEG_CLASS
, NULL
, 0,
555 debug_printf("Creation failed: %s (%i)\n", strerror(-ret
), ret
);
561 dec
->base
.context
= context
;
562 dec
->base
.width
= width
;
563 dec
->base
.height
= height
;
564 dec
->base
.destroy
= nouveau_decoder_destroy
;
565 dec
->base
.begin_frame
= nouveau_decoder_begin_frame
;
566 dec
->base
.decode_macroblock
= nouveau_decoder_decode_macroblock
;
567 dec
->base
.end_frame
= nouveau_decoder_end_frame
;
568 dec
->base
.flush
= nouveau_decoder_flush
;
569 dec
->screen
= screen
;
571 ret
= nouveau_bo_new(dec
->screen
->device
, NOUVEAU_BO_GART
| NOUVEAU_BO_MAP
,
572 0, 1024 * 1024, NULL
, &dec
->cmd_bo
);
576 ret
= nouveau_bo_new(dec
->screen
->device
, NOUVEAU_BO_GART
| NOUVEAU_BO_MAP
,
577 0, width
* height
* 6, NULL
, &dec
->data_bo
);
581 /* we don't need the fence, the kernel sync's for us */
583 ret
= nouveau_bo_new(dec
->screen
->device
, NOUVEAU_BO_GART
| NOUVEAU_BO_MAP
,
584 0, 4096, NULL
, &dec
->fence_bo
);
587 nouveau_bo_map(dec
->fence_bo
, NOUVEAU_BO_RDWR
, NULL
);
588 dec
->fence_map
= dec
->fence_bo
->map
;
589 dec
->fence_map
[0] = 0;
592 nouveau_pushbuf_bufctx(dec
->push
, dec
->bufctx
);
593 nouveau_pushbuf_space(push
, 32, 4, 0);
595 BEGIN_NV04(push
, SUBC_MPEG(NV01_SUBCHAN_OBJECT
), 1);
596 PUSH_DATA (push
, dec
->mpeg
->handle
);
598 BEGIN_NV04(push
, NV31_MPEG(DMA_CMD
), 1);
599 PUSH_DATA (push
, nv04_data
.gart
);
601 BEGIN_NV04(push
, NV31_MPEG(DMA_DATA
), 1);
602 PUSH_DATA (push
, nv04_data
.gart
);
604 BEGIN_NV04(push
, NV31_MPEG(DMA_IMAGE
), 1);
605 PUSH_DATA (push
, nv04_data
.vram
);
607 BEGIN_NV04(push
, NV31_MPEG(PITCH
), 2);
608 PUSH_DATA (push
, width
| NV31_MPEG_PITCH_UNK
);
609 PUSH_DATA (push
, (height
<< NV31_MPEG_SIZE_H__SHIFT
) | width
);
611 BEGIN_NV04(push
, NV31_MPEG(FORMAT
), 2);
613 switch (templ
->entrypoint
) {
614 case PIPE_VIDEO_ENTRYPOINT_BITSTREAM
: PUSH_DATA (push
, 0x100); break;
615 case PIPE_VIDEO_ENTRYPOINT_IDCT
: PUSH_DATA (push
, 1); break;
616 case PIPE_VIDEO_ENTRYPOINT_MC
: PUSH_DATA (push
, 0); break;
621 BEGIN_NV04(push
, NV84_MPEG(DMA_QUERY
), 1);
622 PUSH_DATA (push
, nv04_data
.vram
);
624 BEGIN_NV04(push
, NV84_MPEG(QUERY_OFFSET
), 2);
625 PUSH_DATA (push
, dec
->fence_bo
->offset
);
626 PUSH_DATA (push
, dec
->fence_seq
);
630 ret
= nouveau_vpe_init(dec
);
633 nouveau_vpe_fini(dec
);
637 nouveau_decoder_destroy(&dec
->base
);
641 debug_printf("Using g3dvl renderer\n");
642 return vl_create_decoder(context
, templ
);
645 static struct pipe_sampler_view
**
646 nouveau_video_buffer_sampler_view_planes(struct pipe_video_buffer
*buffer
)
648 struct nouveau_video_buffer
*buf
= (struct nouveau_video_buffer
*)buffer
;
649 struct pipe_sampler_view sv_templ
;
650 struct pipe_context
*pipe
;
655 pipe
= buf
->base
.context
;
657 for (i
= 0; i
< buf
->num_planes
; ++i
) {
658 if (!buf
->sampler_view_planes
[i
]) {
659 memset(&sv_templ
, 0, sizeof(sv_templ
));
660 u_sampler_view_default_template(&sv_templ
, buf
->resources
[i
], buf
->resources
[i
]->format
);
662 if (util_format_get_nr_components(buf
->resources
[i
]->format
) == 1)
663 sv_templ
.swizzle_r
= sv_templ
.swizzle_g
= sv_templ
.swizzle_b
= sv_templ
.swizzle_a
= PIPE_SWIZZLE_RED
;
665 buf
->sampler_view_planes
[i
] = pipe
->create_sampler_view(pipe
, buf
->resources
[i
], &sv_templ
);
666 if (!buf
->sampler_view_planes
[i
])
671 return buf
->sampler_view_planes
;
674 for (i
= 0; i
< buf
->num_planes
; ++i
)
675 pipe_sampler_view_reference(&buf
->sampler_view_planes
[i
], NULL
);
680 static struct pipe_sampler_view
**
681 nouveau_video_buffer_sampler_view_components(struct pipe_video_buffer
*buffer
)
683 struct nouveau_video_buffer
*buf
= (struct nouveau_video_buffer
*)buffer
;
684 struct pipe_sampler_view sv_templ
;
685 struct pipe_context
*pipe
;
686 unsigned i
, j
, component
;
690 pipe
= buf
->base
.context
;
692 for (component
= 0, i
= 0; i
< buf
->num_planes
; ++i
) {
693 unsigned nr_components
= util_format_get_nr_components(buf
->resources
[i
]->format
);
695 for (j
= 0; j
< nr_components
; ++j
, ++component
) {
696 assert(component
< VL_NUM_COMPONENTS
);
698 if (!buf
->sampler_view_components
[component
]) {
699 memset(&sv_templ
, 0, sizeof(sv_templ
));
700 u_sampler_view_default_template(&sv_templ
, buf
->resources
[i
], buf
->resources
[i
]->format
);
701 sv_templ
.swizzle_r
= sv_templ
.swizzle_g
= sv_templ
.swizzle_b
= PIPE_SWIZZLE_RED
+ j
;
702 sv_templ
.swizzle_a
= PIPE_SWIZZLE_ONE
;
703 buf
->sampler_view_components
[component
] = pipe
->create_sampler_view(pipe
, buf
->resources
[i
], &sv_templ
);
704 if (!buf
->sampler_view_components
[component
])
710 return buf
->sampler_view_components
;
713 for (i
= 0; i
< 3; ++i
)
714 pipe_sampler_view_reference(&buf
->sampler_view_components
[i
], NULL
);
719 static struct pipe_surface
**
720 nouveau_video_buffer_surfaces(struct pipe_video_buffer
*buffer
)
722 struct nouveau_video_buffer
*buf
= (struct nouveau_video_buffer
*)buffer
;
723 struct pipe_surface surf_templ
;
724 struct pipe_context
*pipe
;
729 pipe
= buf
->base
.context
;
731 for (i
= 0; i
< buf
->num_planes
; ++i
) {
732 if (!buf
->surfaces
[i
]) {
733 memset(&surf_templ
, 0, sizeof(surf_templ
));
734 surf_templ
.format
= buf
->resources
[i
]->format
;
735 buf
->surfaces
[i
] = pipe
->create_surface(pipe
, buf
->resources
[i
], &surf_templ
);
736 if (!buf
->surfaces
[i
])
741 return buf
->surfaces
;
744 for (i
= 0; i
< buf
->num_planes
; ++i
)
745 pipe_surface_reference(&buf
->surfaces
[i
], NULL
);
751 nouveau_video_buffer_destroy(struct pipe_video_buffer
*buffer
)
753 struct nouveau_video_buffer
*buf
= (struct nouveau_video_buffer
*)buffer
;
758 for (i
= 0; i
< buf
->num_planes
; ++i
) {
759 pipe_surface_reference(&buf
->surfaces
[i
], NULL
);
760 pipe_sampler_view_reference(&buf
->sampler_view_planes
[i
], NULL
);
761 pipe_sampler_view_reference(&buf
->sampler_view_components
[i
], NULL
);
762 pipe_resource_reference(&buf
->resources
[i
], NULL
);
765 pipe_sampler_view_reference(&buf
->sampler_view_components
[i
], NULL
);
770 static struct pipe_video_buffer
*
771 nouveau_video_buffer_create(struct pipe_context
*pipe
,
772 struct nouveau_screen
*screen
,
773 const struct pipe_video_buffer
*templat
)
775 struct nouveau_video_buffer
*buffer
;
776 struct pipe_resource templ
;
777 unsigned width
, height
;
779 /* Only do a linear surface when a hardware decoder is used
780 * hardware decoder is only supported on some chipsets
781 * and it only supports the NV12 format
783 if (templat
->buffer_format
!= PIPE_FORMAT_NV12
|| getenv("XVMC_VL") ||
784 (screen
->device
->chipset
>= 0x98 && screen
->device
->chipset
!= 0xa0) ||
785 screen
->device
->chipset
< 0x31 || screen
->device
->chipset
== 0x35)
786 return vl_video_buffer_create(pipe
, templat
);
788 assert(templat
->chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_420
);
789 width
= align(templat
->width
, 64);
790 height
= align(templat
->height
, 64);
792 buffer
= CALLOC_STRUCT(nouveau_video_buffer
);
796 buffer
->base
.context
= pipe
;
797 buffer
->base
.destroy
= nouveau_video_buffer_destroy
;
798 buffer
->base
.get_sampler_view_planes
= nouveau_video_buffer_sampler_view_planes
;
799 buffer
->base
.get_sampler_view_components
= nouveau_video_buffer_sampler_view_components
;
800 buffer
->base
.get_surfaces
= nouveau_video_buffer_surfaces
;
801 buffer
->base
.chroma_format
= templat
->chroma_format
;
802 buffer
->base
.buffer_format
= templat
->buffer_format
;
803 buffer
->base
.width
= width
;
804 buffer
->base
.height
= height
;
805 buffer
->num_planes
= 2;
807 memset(&templ
, 0, sizeof(templ
));
808 templ
.target
= PIPE_TEXTURE_2D
;
809 templ
.format
= PIPE_FORMAT_R8_UNORM
;
810 templ
.width0
= width
;
811 templ
.height0
= height
;
813 templ
.array_size
= 1;
814 templ
.bind
= PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
;
815 templ
.usage
= PIPE_USAGE_STATIC
;
816 templ
.flags
= NOUVEAU_RESOURCE_FLAG_LINEAR
;
818 buffer
->resources
[0] = pipe
->screen
->resource_create(pipe
->screen
, &templ
);
819 if (!buffer
->resources
[0])
823 templ
.format
= PIPE_FORMAT_R8G8_UNORM
;
824 buffer
->resources
[1] = pipe
->screen
->resource_create(pipe
->screen
, &templ
);
825 if (!buffer
->resources
[1])
827 return &buffer
->base
;
830 nouveau_video_buffer_destroy(&buffer
->base
);
835 nouveau_screen_get_video_param(struct pipe_screen
*pscreen
,
836 enum pipe_video_profile profile
,
837 enum pipe_video_cap param
)
840 case PIPE_VIDEO_CAP_SUPPORTED
:
841 return vl_profile_supported(pscreen
, profile
);
842 case PIPE_VIDEO_CAP_NPOT_TEXTURES
:
844 case PIPE_VIDEO_CAP_MAX_WIDTH
:
845 case PIPE_VIDEO_CAP_MAX_HEIGHT
:
846 return vl_video_buffer_max_size(pscreen
);
847 case PIPE_VIDEO_CAP_PREFERED_FORMAT
:
848 return PIPE_FORMAT_NV12
;
849 case PIPE_VIDEO_CAP_PREFERS_INTERLACED
:
851 case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED
:
853 case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE
:
855 case PIPE_VIDEO_CAP_MAX_LEVEL
:
856 return vl_level_supported(pscreen
, profile
);
858 debug_printf("unknown video param: %d\n", param
);
864 nouveau_screen_init_vdec(struct nouveau_screen
*screen
)
866 screen
->base
.get_video_param
= nouveau_screen_get_video_param
;
867 screen
->base
.is_video_format_supported
= vl_video_buffer_is_format_supported
;
870 static struct pipe_video_codec
*
871 nouveau_context_create_decoder(struct pipe_context
*context
,
872 const struct pipe_video_codec
*templ
)
874 struct nouveau_screen
*screen
= nouveau_context(context
)->screen
;
875 return nouveau_create_decoder(context
, templ
, screen
);
878 static struct pipe_video_buffer
*
879 nouveau_context_video_buffer_create(struct pipe_context
*pipe
,
880 const struct pipe_video_buffer
*templat
)
882 struct nouveau_screen
*screen
= nouveau_context(pipe
)->screen
;
883 return nouveau_video_buffer_create(pipe
, screen
, templat
);
887 nouveau_context_init_vdec(struct nouveau_context
*nv
)
889 nv
->pipe
.create_video_codec
= nouveau_context_create_decoder
;
890 nv
->pipe
.create_video_buffer
= nouveau_context_video_buffer_create
;