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 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
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 "nvfx/nvfx_context.h"
31 #include "nvfx/nvfx_resource.h"
32 #include "nouveau/nouveau_bo.h"
33 #include "nouveau/nouveau_buffer.h"
34 #include "util/u_video.h"
35 #include "util/u_format.h"
36 #include "util/u_sampler.h"
37 #include "nouveau/nouveau_device.h"
38 #include "nouveau_winsys.h"
41 nouveau_video_is_nvfx(struct nouveau_decoder
*dec
) {
42 if (dec
->screen
->device
->chipset
< 0x50)
44 if (dec
->screen
->device
->chipset
>= 0x60 && dec
->screen
->device
->chipset
< 0x70)
50 nouveau_vpe_init(struct nouveau_decoder
*dec
) {
54 ret
= nouveau_bo_map(dec
->cmd_bo
, NOUVEAU_BO_RDWR
);
56 debug_printf("Mapping cmd bo: %s\n", strerror(-ret
));
59 ret
= nouveau_bo_map(dec
->data_bo
, NOUVEAU_BO_RDWR
);
61 nouveau_bo_unmap(dec
->cmd_bo
);
62 debug_printf("Mapping data bo: %s\n", strerror(-ret
));
65 dec
->cmds
= dec
->cmd_bo
->map
;
66 dec
->data
= dec
->data_bo
->map
;
71 nouveau_vpe_synch(struct nouveau_decoder
*dec
) {
72 struct nouveau_channel
*chan
= dec
->screen
->channel
;
75 BEGIN_RING(chan
, dec
->mpeg
, NV84_MPEG_QUERY_COUNTER
, 1);
76 OUT_RING(chan
, ++dec
->fence_seq
);
78 while (dec
->fence_map
[0] != dec
->fence_seq
)
86 nouveau_vpe_fini(struct nouveau_decoder
*dec
) {
87 struct nouveau_channel
*chan
= dec
->screen
->channel
;
91 nouveau_bo_unmap(dec
->data_bo
);
92 nouveau_bo_unmap(dec
->cmd_bo
);
94 MARK_RING(chan
, 8, 2);
95 BEGIN_RING(chan
, dec
->mpeg
, NV31_MPEG_CMD_OFFSET
, 2);
96 OUT_RELOCl(chan
, dec
->cmd_bo
, 0, NOUVEAU_BO_RD
|NOUVEAU_BO_GART
);
97 OUT_RING(chan
, dec
->ofs
* 4);
99 BEGIN_RING(chan
, dec
->mpeg
, NV31_MPEG_DATA_OFFSET
, 2);
100 OUT_RELOCl(chan
, dec
->data_bo
, 0, NOUVEAU_BO_RD
|NOUVEAU_BO_GART
);
101 OUT_RING(chan
, dec
->data_pos
* 4);
103 BEGIN_RING(chan
, dec
->mpeg
, NV31_MPEG_EXEC
, 1);
106 nouveau_vpe_synch(dec
);
107 dec
->ofs
= dec
->data_pos
= dec
->num_surfaces
= 0;
108 dec
->cmds
= dec
->data
= NULL
;
109 dec
->current
= dec
->future
= dec
->past
= 8;
113 nouveau_vpe_mb_dct_blocks(struct nouveau_decoder
*dec
, const struct pipe_mpeg12_macroblock
*mb
)
116 unsigned cbp
= mb
->coded_block_pattern
;
117 short *db
= mb
->blocks
;
118 for (cbb
= 0x20; cbb
> 0; cbb
>>= 1) {
120 static const int lookup
[64] = {
121 0, 1, 8,16, 9, 2, 3,10,
122 17,24,32,25,18,11, 4, 5,
123 12,19,26,33,40,48,41,34,
124 27,20,13, 6, 7,14,21,28,
125 35,42,49,56,57,50,43,36,
126 29,22,15,23,30,37,44,51,
127 58,59,52,45,38,31,39,46,
128 53,60,61,54,47,55,62,63
130 int i
, j
= 0, found
= 0;
131 for (i
= 0; i
< 64; ++i
) {
132 if (!db
[lookup
[i
]]) { j
+= 2; continue; }
133 dec
->data
[dec
->data_pos
++] = (db
[lookup
[i
]] << 16) | j
;
138 dec
->data
[dec
->data_pos
- 1] |= 1;
140 dec
->data
[dec
->data_pos
++] = 1;
142 } else if (mb
->macroblock_type
& PIPE_MPEG12_MB_TYPE_INTRA
) {
143 dec
->data
[dec
->data_pos
++] = 1;
149 nouveau_vpe_mb_data_blocks(struct nouveau_decoder
*dec
, const struct pipe_mpeg12_macroblock
*mb
)
152 unsigned cbp
= mb
->coded_block_pattern
;
153 short *db
= mb
->blocks
;
154 for (cbb
= 0x20; cbb
> 0; cbb
>>= 1) {
156 memcpy(&dec
->data
[dec
->data_pos
], db
, 128);
159 } else if (mb
->macroblock_type
& PIPE_MPEG12_MB_TYPE_INTRA
) {
160 memset(&dec
->data
[dec
->data_pos
], 0, 128);
167 nouveau_vpe_mb_dct_header(struct nouveau_decoder
*dec
,
168 const struct pipe_mpeg12_macroblock
*mb
,
171 unsigned base_dct
, cbp
;
172 bool intra
= mb
->macroblock_type
& PIPE_MPEG12_MB_TYPE_INTRA
;
173 unsigned x
= mb
->x
* 16;
174 unsigned y
= luma
? mb
->y
* 16 : mb
->y
* 8;
176 /* Setup the base dct header */
177 base_dct
= dec
->current
<< NV17_MPEG_CMD_CHROMA_MB_HEADER_SURFACE__SHIFT
;
178 base_dct
|= NV17_MPEG_CMD_CHROMA_MB_HEADER_RUN_SINGLE
;
181 base_dct
|= NV17_MPEG_CMD_CHROMA_MB_HEADER_X_COORD_EVEN
;
185 cbp
= mb
->coded_block_pattern
;
187 if (dec
->picture_structure
== PIPE_MPEG12_PICTURE_STRUCTURE_FRAME
) {
188 base_dct
|= NV17_MPEG_CMD_CHROMA_MB_HEADER_TYPE_FRAME
;
189 if (luma
&& mb
->macroblock_modes
.bits
.dct_type
== PIPE_MPEG12_DCT_TYPE_FIELD
)
190 base_dct
|= NV17_MPEG_CMD_CHROMA_MB_HEADER_FRAME_DCT_TYPE_FIELD
;
192 if (dec
->picture_structure
== PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_BOTTOM
)
193 base_dct
|= NV17_MPEG_CMD_CHROMA_MB_HEADER_FIELD_BOTTOM
;
199 base_dct
|= NV17_MPEG_CMD_LUMA_MB_HEADER_OP_LUMA_MB_HEADER
;
200 base_dct
|= (cbp
>> 2) << NV17_MPEG_CMD_LUMA_MB_HEADER_CBP__SHIFT
;
202 base_dct
|= NV17_MPEG_CMD_CHROMA_MB_HEADER_OP_CHROMA_MB_HEADER
;
203 base_dct
|= (cbp
& 3) << NV17_MPEG_CMD_CHROMA_MB_HEADER_CBP__SHIFT
;
205 nouveau_vpe_write(dec
, base_dct
);
206 nouveau_vpe_write(dec
, NV17_MPEG_CMD_MB_COORDS_OP_MB_COORDS
|
207 x
| (y
<< NV17_MPEG_CMD_MB_COORDS_Y__SHIFT
));
210 static INLINE
unsigned int
211 nouveau_vpe_mb_mv_flags(bool luma
, int mv_h
, int mv_v
, bool forward
, bool first
, bool vert
)
213 unsigned mc_header
= 0;
215 mc_header
|= NV17_MPEG_CMD_LUMA_MV_HEADER_OP_LUMA_MV_HEADER
;
217 mc_header
|= NV17_MPEG_CMD_CHROMA_MV_HEADER_OP_CHROMA_MV_HEADER
;
219 mc_header
|= NV17_MPEG_CMD_CHROMA_MV_HEADER_X_HALF
;
221 mc_header
|= NV17_MPEG_CMD_CHROMA_MV_HEADER_Y_HALF
;
223 mc_header
|= NV17_MPEG_CMD_CHROMA_MV_HEADER_DIRECTION_BACKWARD
;
225 mc_header
|= NV17_MPEG_CMD_CHROMA_MV_HEADER_IDX
;
227 mc_header
|= NV17_MPEG_CMD_LUMA_MV_HEADER_FIELD_BOTTOM
;
231 static unsigned pos(int pos
, int mov
, int max
) {
240 /* because we want -1 / 2 = -1 */
241 static int div_down(int val
, int mult
) {
246 static int div_up(int val
, int mult
) {
252 nouveau_vpe_mb_mv(struct nouveau_decoder
*dec
, unsigned mc_header
,
253 bool luma
, bool frame
, bool forward
, bool vert
,
254 int x
, int y
, const short motions
[2],
255 unsigned surface
, bool first
)
258 int mv_horizontal
= motions
[0];
259 int mv_vertical
= motions
[1];
260 int mv2
= mc_header
& NV17_MPEG_CMD_CHROMA_MV_HEADER_COUNT_2
;
261 unsigned width
= dec
->base
.width
;
262 unsigned height
= dec
->base
.height
;
264 mv_vertical
= div_down(mv_vertical
, 2);
265 assert(frame
); // Untested for non-frames
269 mc_header
|= surface
<< NV17_MPEG_CMD_CHROMA_MV_HEADER_SURFACE__SHIFT
;
271 mv_vertical
= div_up(mv_vertical
, 2);
272 mv_horizontal
= div_up(mv_horizontal
, 2);
275 mc_header
|= nouveau_vpe_mb_mv_flags(luma
, mv_horizontal
, mv_vertical
, forward
, first
, vert
);
276 nouveau_vpe_write(dec
, mc_header
);
278 mc_vector
= NV17_MPEG_CMD_MV_COORDS_OP_MV_COORDS
;
280 mc_vector
|= pos(x
, div_down(mv_horizontal
, 2), width
);
282 mc_vector
|= pos(x
, mv_horizontal
& ~1, width
);
284 mc_vector
|= pos(y
, div_down(mv_vertical
, 2), height
) << NV17_MPEG_CMD_MV_COORDS_Y__SHIFT
;
286 mc_vector
|= pos(y
, mv_vertical
& ~1, height
) << NV17_MPEG_CMD_MV_COORDS_Y__SHIFT
;
287 nouveau_vpe_write(dec
, mc_vector
);
291 nouveau_vpe_mb_mv_header(struct nouveau_decoder
*dec
,
292 const struct pipe_mpeg12_macroblock
*mb
,
295 bool frame
= dec
->picture_structure
== PIPE_MPEG12_PICTURE_STRUCTURE_FRAME
;
297 bool forward
, backward
;
298 int y
, y2
, x
= mb
->x
* 16;
300 y
= mb
->y
* (frame
? 16 : 32);
302 y
= mb
->y
* (frame
? 8 : 16);
306 y2
= y
+ (luma
? 16 : 8);
308 forward
= mb
->macroblock_type
& PIPE_MPEG12_MB_TYPE_MOTION_FORWARD
;
309 backward
= mb
->macroblock_type
& PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD
;
310 assert(!forward
|| dec
->past
< 8);
311 assert(!backward
|| dec
->future
< 8);
313 switch (mb
->macroblock_modes
.bits
.frame_motion_type
) {
314 case PIPE_MPEG12_MO_TYPE_FRAME
: goto mv1
;
315 case PIPE_MPEG12_MO_TYPE_FIELD
: goto mv2
;
316 case PIPE_MPEG12_MO_TYPE_DUAL_PRIME
: {
317 base
= NV17_MPEG_CMD_CHROMA_MV_HEADER_COUNT_2
;
319 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, TRUE
, FALSE
,
320 x
, y
, mb
->PMV
[0][0], dec
->past
, TRUE
);
321 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, TRUE
, TRUE
,
322 x
, y2
, mb
->PMV
[0][0], dec
->past
, FALSE
);
324 if (backward
&& forward
) {
325 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, !forward
, TRUE
,
326 x
, y
, mb
->PMV
[1][0], dec
->future
, TRUE
);
327 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, !forward
, FALSE
,
328 x
, y2
, mb
->PMV
[1][1], dec
->future
, FALSE
);
329 } else assert(!backward
);
335 switch (mb
->macroblock_modes
.bits
.field_motion_type
) {
336 case PIPE_MPEG12_MO_TYPE_FIELD
: goto mv1
;
337 case PIPE_MPEG12_MO_TYPE_16x8
: goto mv2
;
338 case PIPE_MPEG12_MO_TYPE_DUAL_PRIME
: {
339 base
= NV17_MPEG_CMD_CHROMA_MV_HEADER_MV_SPLIT_HALF_MB
;
341 base
|= NV17_MPEG_CMD_CHROMA_MV_HEADER_TYPE_FRAME
;
343 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, TRUE
,
344 dec
->picture_structure
!= PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_TOP
,
345 x
, y
, mb
->PMV
[0][0], dec
->past
, TRUE
);
346 if (backward
&& forward
)
347 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, FALSE
,
348 dec
->picture_structure
== PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_TOP
,
349 x
, y
, mb
->PMV
[0][1], dec
->future
, TRUE
);
350 else assert(!backward
);
359 base
= NV17_MPEG_CMD_CHROMA_MV_HEADER_MV_SPLIT_HALF_MB
;
361 base
|= NV17_MPEG_CMD_CHROMA_MV_HEADER_TYPE_FRAME
;
364 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, TRUE
, FALSE
,
365 x
, y
, mb
->PMV
[0][0], dec
->past
, TRUE
);
367 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, !forward
, FALSE
,
368 x
, y
, mb
->PMV
[0][1], dec
->future
, TRUE
);
372 base
= NV17_MPEG_CMD_CHROMA_MV_HEADER_COUNT_2
;
374 base
|= NV17_MPEG_CMD_CHROMA_MV_HEADER_MV_SPLIT_HALF_MB
;
376 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, TRUE
,
377 mb
->motion_vertical_field_select
& PIPE_MPEG12_FS_FIRST_FORWARD
,
378 x
, y
, mb
->PMV
[0][0], dec
->past
, TRUE
);
379 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, TRUE
,
380 mb
->motion_vertical_field_select
& PIPE_MPEG12_FS_SECOND_FORWARD
,
381 x
, y2
, mb
->PMV
[1][0], dec
->past
, FALSE
);
384 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, !forward
,
385 mb
->motion_vertical_field_select
& PIPE_MPEG12_FS_FIRST_BACKWARD
,
386 x
, y
, mb
->PMV
[0][1], dec
->future
, TRUE
);
387 nouveau_vpe_mb_mv(dec
, base
, luma
, frame
, !forward
,
388 mb
->motion_vertical_field_select
& PIPE_MPEG12_FS_SECOND_BACKWARD
,
389 x
, y2
, mb
->PMV
[1][1], dec
->future
, FALSE
);
394 nouveau_decoder_surface_index(struct nouveau_decoder
*dec
,
395 struct pipe_video_buffer
*buffer
)
397 struct nouveau_video_buffer
*buf
= (struct nouveau_video_buffer
*)buffer
;
398 struct nouveau_channel
*chan
= dec
->screen
->channel
;
399 struct nouveau_bo
*bo_y
, *bo_c
;
404 for (i
= 0; i
< dec
->num_surfaces
; ++i
) {
405 if (dec
->surfaces
[i
] == buf
)
409 dec
->surfaces
[i
] = buf
;
412 if (nouveau_video_is_nvfx(dec
)) {
413 bo_y
= ((struct nvfx_resource
*)buf
->resources
[0])->bo
;
414 bo_c
= ((struct nvfx_resource
*)buf
->resources
[1])->bo
;
416 bo_y
= ((struct nv04_resource
*)buf
->resources
[0])->bo
;
417 bo_c
= ((struct nv04_resource
*)buf
->resources
[1])->bo
;
419 MARK_RING(chan
, 3, 2);
420 BEGIN_RING(chan
, dec
->mpeg
, NV31_MPEG_IMAGE_Y_OFFSET(i
), 2);
421 OUT_RELOCl(chan
, bo_y
, 0, NOUVEAU_BO_RDWR
);
422 OUT_RELOCl(chan
, bo_c
, 0, NOUVEAU_BO_RDWR
);
427 nouveau_decoder_set_picture_parameters(struct pipe_video_decoder
*decoder
,
428 struct pipe_picture_desc
*picture_desc
)
430 struct nouveau_decoder
*dec
= (struct nouveau_decoder
*)decoder
;
431 struct pipe_mpeg12_picture_desc
*desc
;
432 desc
= (struct pipe_mpeg12_picture_desc
*)picture_desc
;
433 dec
->picture_structure
= desc
->picture_structure
;
437 nouveau_decoder_set_reference_frames(struct pipe_video_decoder
*decoder
,
438 struct pipe_video_buffer
**buffers
,
441 struct nouveau_decoder
*dec
= (struct nouveau_decoder
*)decoder
;
442 if (count
>= 1 && buffers
[0])
443 dec
->past
= nouveau_decoder_surface_index(dec
, buffers
[0]);
444 if (count
>= 2 && buffers
[1])
445 dec
->future
= nouveau_decoder_surface_index(dec
, buffers
[1]);
449 nouveau_decoder_set_decode_target(struct pipe_video_decoder
*decoder
,
450 struct pipe_video_buffer
*buffer
)
452 struct nouveau_decoder
*dec
= (struct nouveau_decoder
*)decoder
;
453 dec
->current
= nouveau_decoder_surface_index(dec
, buffer
);
457 nouveau_decoder_decode_macroblock(struct pipe_video_decoder
*decoder
,
458 const struct pipe_macroblock
*pipe_mb
,
459 unsigned num_macroblocks
)
461 struct nouveau_decoder
*dec
= (struct nouveau_decoder
*)decoder
;
462 const struct pipe_mpeg12_macroblock
*mb
;
464 assert(dec
->current
< 8);
466 if (nouveau_vpe_init(dec
)) return;
467 mb
= (const struct pipe_mpeg12_macroblock
*)pipe_mb
;
468 for (i
= 0; i
< num_macroblocks
; ++i
, mb
++) {
469 if (mb
->macroblock_type
& PIPE_MPEG12_MB_TYPE_INTRA
) {
470 nouveau_vpe_mb_dct_header(dec
, mb
, TRUE
);
471 nouveau_vpe_mb_dct_header(dec
, mb
, FALSE
);
473 nouveau_vpe_mb_mv_header(dec
, mb
, TRUE
);
474 nouveau_vpe_mb_dct_header(dec
, mb
, TRUE
);
476 nouveau_vpe_mb_mv_header(dec
, mb
, FALSE
);
477 nouveau_vpe_mb_dct_header(dec
, mb
, FALSE
);
479 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
480 nouveau_vpe_mb_dct_blocks(dec
, mb
);
482 nouveau_vpe_mb_data_blocks(dec
, mb
);
487 nouveau_decoder_flush(struct pipe_video_decoder
*decoder
)
489 struct nouveau_decoder
*dec
= (struct nouveau_decoder
*)decoder
;
491 nouveau_vpe_fini(dec
);
495 nouveau_decoder_destroy(struct pipe_video_decoder
*decoder
)
497 struct nouveau_decoder
*dec
= (struct nouveau_decoder
*)decoder
;
500 nouveau_bo_unmap(dec
->data_bo
);
501 nouveau_bo_unmap(dec
->cmd_bo
);
505 nouveau_bo_ref(NULL
, &dec
->data_bo
);
507 nouveau_bo_ref(NULL
, &dec
->cmd_bo
);
509 nouveau_bo_ref(NULL
, &dec
->fence_bo
);
510 nouveau_grobj_free(&dec
->mpeg
);
515 nouveau_decoder_begin_frame(struct pipe_video_decoder
*decoder
)
520 nouveau_decoder_end_frame(struct pipe_video_decoder
*decoder
)
524 static struct pipe_video_decoder
*
525 nouveau_create_decoder(struct pipe_context
*context
,
526 struct nouveau_screen
*screen
,
527 enum pipe_video_profile profile
,
528 enum pipe_video_entrypoint entrypoint
,
529 enum pipe_video_chroma_format chroma_format
,
530 unsigned width
, unsigned height
,
531 unsigned max_references
, bool expect_chunked_decode
)
533 struct nouveau_channel
*chan
= screen
->channel
;
534 struct nouveau_grobj
*mpeg
= NULL
;
535 struct nouveau_decoder
*dec
;
537 bool is8274
= screen
->device
->chipset
> 0x80;
539 debug_printf("Acceleration level: %s\n", entrypoint
<= PIPE_VIDEO_ENTRYPOINT_BITSTREAM
? "bit":
540 entrypoint
== PIPE_VIDEO_ENTRYPOINT_IDCT
? "IDCT" : "MC");
542 if (getenv("XVMC_VL"))
544 if (u_reduce_video_profile(profile
) != PIPE_VIDEO_CODEC_MPEG12
)
546 if (screen
->device
->chipset
>= 0x98 && screen
->device
->chipset
!= 0xa0)
549 width
= align(width
, 64);
550 height
= align(height
, 64);
553 ret
= nouveau_grobj_alloc(chan
, 0xbeef8274, 0x8274, &mpeg
);
555 ret
= nouveau_grobj_alloc(chan
, 0xbeef8274, 0x3174, &mpeg
);
557 debug_printf("Creation failed: %s (%i)\n", strerror(-ret
), ret
);
561 dec
= CALLOC_STRUCT(nouveau_decoder
);
563 nouveau_grobj_free(&mpeg
);
567 dec
->base
.context
= context
;
568 dec
->base
.profile
= profile
;
569 dec
->base
.entrypoint
= entrypoint
;
570 dec
->base
.chroma_format
= chroma_format
;
571 dec
->base
.width
= width
;
572 dec
->base
.height
= height
;
573 dec
->base
.max_references
= max_references
;
574 dec
->base
.destroy
= nouveau_decoder_destroy
;
575 dec
->base
.begin_frame
= nouveau_decoder_begin_frame
;
576 dec
->base
.end_frame
= nouveau_decoder_end_frame
;
577 dec
->base
.set_decode_target
= nouveau_decoder_set_decode_target
;
578 dec
->base
.set_picture_parameters
= nouveau_decoder_set_picture_parameters
;
579 dec
->base
.set_reference_frames
= nouveau_decoder_set_reference_frames
;
580 dec
->base
.decode_macroblock
= nouveau_decoder_decode_macroblock
;
581 dec
->base
.flush
= nouveau_decoder_flush
;
582 dec
->screen
= screen
;
584 ret
= nouveau_bo_new(dec
->screen
->device
, NOUVEAU_BO_GART
, 0, 1024 * 1024, &dec
->cmd_bo
);
588 ret
= nouveau_bo_new(dec
->screen
->device
, NOUVEAU_BO_GART
, 0, width
* height
* 6, &dec
->data_bo
);
592 ret
= nouveau_bo_new(dec
->screen
->device
, NOUVEAU_BO_GART
|NOUVEAU_BO_MAP
, 0, 4096,
596 nouveau_bo_map(dec
->fence_bo
, NOUVEAU_BO_RDWR
);
597 dec
->fence_map
= dec
->fence_bo
->map
;
598 nouveau_bo_unmap(dec
->fence_bo
);
599 dec
->fence_map
[0] = 0;
602 MARK_RING(chan
, 25, 3);
604 MARK_RING(chan
, 20, 2);
606 BEGIN_RING(chan
, mpeg
, NV31_MPEG_DMA_CMD
, 1);
607 OUT_RING(chan
, chan
->vram
->handle
);
609 BEGIN_RING(chan
, mpeg
, NV31_MPEG_DMA_DATA
, 1);
610 OUT_RING(chan
, chan
->vram
->handle
);
612 BEGIN_RING(chan
, mpeg
, NV31_MPEG_DMA_IMAGE
, 1);
613 OUT_RING(chan
, chan
->vram
->handle
);
615 BEGIN_RING(chan
, mpeg
, NV31_MPEG_PITCH
, 2);
616 OUT_RING(chan
, width
| NV31_MPEG_PITCH_UNK
);
617 OUT_RING(chan
, (height
<< NV31_MPEG_SIZE_H__SHIFT
) | width
);
619 BEGIN_RING(chan
, mpeg
, NV31_MPEG_FORMAT
, 2);
621 switch (entrypoint
) {
622 case PIPE_VIDEO_ENTRYPOINT_BITSTREAM
: OUT_RING(chan
, 0x100); break;
623 case PIPE_VIDEO_ENTRYPOINT_IDCT
: OUT_RING(chan
, 1); break;
624 case PIPE_VIDEO_ENTRYPOINT_MC
: OUT_RING(chan
, 0); break;
629 BEGIN_RING(chan
, mpeg
, NV84_MPEG_DMA_QUERY
, 1);
630 OUT_RING(chan
, chan
->vram
->handle
);
632 BEGIN_RING(chan
, mpeg
, NV84_MPEG_QUERY_OFFSET
, 2);
633 OUT_RELOCl(chan
, dec
->fence_bo
, 0, NOUVEAU_BO_WR
|NOUVEAU_BO_GART
);
634 OUT_RING(chan
, dec
->fence_seq
);
637 ret
= nouveau_vpe_init(dec
);
640 nouveau_vpe_fini(dec
);
644 nouveau_decoder_destroy(&dec
->base
);
648 debug_printf("Using g3dvl renderer\n");
649 return vl_create_decoder(context
, profile
, entrypoint
,
650 chroma_format
, width
, height
,
651 max_references
, expect_chunked_decode
);
654 static struct pipe_sampler_view
**
655 nouveau_video_buffer_sampler_view_planes(struct pipe_video_buffer
*buffer
)
657 struct nouveau_video_buffer
*buf
= (struct nouveau_video_buffer
*)buffer
;
658 struct pipe_sampler_view sv_templ
;
659 struct pipe_context
*pipe
;
664 pipe
= buf
->base
.context
;
666 for (i
= 0; i
< buf
->num_planes
; ++i
) {
667 if (!buf
->sampler_view_planes
[i
]) {
668 memset(&sv_templ
, 0, sizeof(sv_templ
));
669 u_sampler_view_default_template(&sv_templ
, buf
->resources
[i
], buf
->resources
[i
]->format
);
671 if (util_format_get_nr_components(buf
->resources
[i
]->format
) == 1)
672 sv_templ
.swizzle_r
= sv_templ
.swizzle_g
= sv_templ
.swizzle_b
= sv_templ
.swizzle_a
= PIPE_SWIZZLE_RED
;
674 buf
->sampler_view_planes
[i
] = pipe
->create_sampler_view(pipe
, buf
->resources
[i
], &sv_templ
);
675 if (!buf
->sampler_view_planes
[i
])
680 return buf
->sampler_view_planes
;
683 for (i
= 0; i
< buf
->num_planes
; ++i
)
684 pipe_sampler_view_reference(&buf
->sampler_view_planes
[i
], NULL
);
689 static struct pipe_sampler_view
**
690 nouveau_video_buffer_sampler_view_components(struct pipe_video_buffer
*buffer
)
692 struct nouveau_video_buffer
*buf
= (struct nouveau_video_buffer
*)buffer
;
693 struct pipe_sampler_view sv_templ
;
694 struct pipe_context
*pipe
;
695 unsigned i
, j
, component
;
699 pipe
= buf
->base
.context
;
701 for (component
= 0, i
= 0; i
< buf
->num_planes
; ++i
) {
702 unsigned nr_components
= util_format_get_nr_components(buf
->resources
[i
]->format
);
704 for (j
= 0; j
< nr_components
; ++j
, ++component
) {
705 assert(component
< VL_MAX_PLANES
);
707 if (!buf
->sampler_view_components
[component
]) {
708 memset(&sv_templ
, 0, sizeof(sv_templ
));
709 u_sampler_view_default_template(&sv_templ
, buf
->resources
[i
], buf
->resources
[i
]->format
);
710 sv_templ
.swizzle_r
= sv_templ
.swizzle_g
= sv_templ
.swizzle_b
= PIPE_SWIZZLE_RED
+ j
;
711 sv_templ
.swizzle_a
= PIPE_SWIZZLE_ONE
;
712 buf
->sampler_view_components
[component
] = pipe
->create_sampler_view(pipe
, buf
->resources
[i
], &sv_templ
);
713 if (!buf
->sampler_view_components
[component
])
719 return buf
->sampler_view_components
;
722 for (i
= 0; i
< 3; ++i
)
723 pipe_sampler_view_reference(&buf
->sampler_view_components
[i
], NULL
);
728 static struct pipe_surface
**
729 nouveau_video_buffer_surfaces(struct pipe_video_buffer
*buffer
)
731 struct nouveau_video_buffer
*buf
= (struct nouveau_video_buffer
*)buffer
;
732 struct pipe_surface surf_templ
;
733 struct pipe_context
*pipe
;
738 pipe
= buf
->base
.context
;
740 for (i
= 0; i
< buf
->num_planes
; ++i
) {
741 if (!buf
->surfaces
[i
]) {
742 memset(&surf_templ
, 0, sizeof(surf_templ
));
743 surf_templ
.format
= buf
->resources
[i
]->format
;
744 surf_templ
.usage
= PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
;
745 buf
->surfaces
[i
] = pipe
->create_surface(pipe
, buf
->resources
[i
], &surf_templ
);
746 if (!buf
->surfaces
[i
])
751 return buf
->surfaces
;
754 for (i
= 0; i
< buf
->num_planes
; ++i
)
755 pipe_surface_reference(&buf
->surfaces
[i
], NULL
);
761 nouveau_video_buffer_destroy(struct pipe_video_buffer
*buffer
)
763 struct nouveau_video_buffer
*buf
= (struct nouveau_video_buffer
*)buffer
;
768 for (i
= 0; i
< buf
->num_planes
; ++i
) {
769 pipe_surface_reference(&buf
->surfaces
[i
], NULL
);
770 pipe_sampler_view_reference(&buf
->sampler_view_planes
[i
], NULL
);
771 pipe_sampler_view_reference(&buf
->sampler_view_components
[i
], NULL
);
772 pipe_resource_reference(&buf
->resources
[i
], NULL
);
775 pipe_sampler_view_reference(&buf
->sampler_view_components
[i
], NULL
);
780 static struct pipe_video_buffer
*
781 nouveau_video_buffer_create(struct pipe_context
*pipe
,
782 struct nouveau_screen
*screen
,
783 enum pipe_format buffer_format
,
784 enum pipe_video_chroma_format chroma_format
,
785 unsigned width
, unsigned height
)
787 struct nouveau_video_buffer
*buffer
;
788 struct pipe_resource templ
;
790 /* Only do a linear surface when a hardware decoder is used
791 * hardware decoder is only supported on some chipsets
792 * and it only supports the NV12 format
794 if (buffer_format
!= PIPE_FORMAT_NV12
|| getenv("XVMC_VL") ||
795 (screen
->device
->chipset
>= 0x98 && screen
->device
->chipset
!= 0xa0))
796 return vl_video_buffer_create(pipe
, buffer_format
, chroma_format
, width
, height
);
798 assert(chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_420
);
799 width
= align(width
, 64);
800 height
= align(height
, 64);
802 buffer
= CALLOC_STRUCT(nouveau_video_buffer
);
806 buffer
->base
.context
= pipe
;
807 buffer
->base
.destroy
= nouveau_video_buffer_destroy
;
808 buffer
->base
.get_sampler_view_planes
= nouveau_video_buffer_sampler_view_planes
;
809 buffer
->base
.get_sampler_view_components
= nouveau_video_buffer_sampler_view_components
;
810 buffer
->base
.get_surfaces
= nouveau_video_buffer_surfaces
;
811 buffer
->base
.chroma_format
= chroma_format
;
812 buffer
->base
.width
= width
;
813 buffer
->base
.height
= height
;
814 buffer
->num_planes
= 2;
816 memset(&templ
, 0, sizeof(templ
));
817 templ
.target
= PIPE_TEXTURE_2D
;
818 templ
.format
= PIPE_FORMAT_R8_UNORM
;
819 templ
.width0
= width
;
820 templ
.height0
= height
;
822 templ
.array_size
= 1;
823 templ
.bind
= PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
;
824 templ
.usage
= PIPE_USAGE_STATIC
;
825 templ
.flags
= NOUVEAU_RESOURCE_FLAG_LINEAR
;
827 buffer
->resources
[0] = pipe
->screen
->resource_create(pipe
->screen
, &templ
);
828 if (!buffer
->resources
[0])
832 templ
.format
= PIPE_FORMAT_R8G8_UNORM
;
833 buffer
->resources
[1] = pipe
->screen
->resource_create(pipe
->screen
, &templ
);
834 if (!buffer
->resources
[1])
836 return &buffer
->base
;
839 nouveau_video_buffer_destroy(&buffer
->base
);
844 nouveau_screen_get_video_param(struct pipe_screen
*pscreen
,
845 enum pipe_video_profile profile
,
846 enum pipe_video_cap param
)
849 case PIPE_VIDEO_CAP_SUPPORTED
:
850 return vl_profile_supported(pscreen
, profile
);
851 case PIPE_VIDEO_CAP_NPOT_TEXTURES
:
853 case PIPE_VIDEO_CAP_MAX_WIDTH
:
854 case PIPE_VIDEO_CAP_MAX_HEIGHT
:
855 return vl_video_buffer_max_size(pscreen
);
857 debug_printf("unknown video param: %d\n", param
);
863 nouveau_screen_init_vdec(struct nouveau_screen
*screen
)
865 screen
->base
.get_video_param
= nouveau_screen_get_video_param
;
866 screen
->base
.is_video_format_supported
= vl_video_buffer_is_format_supported
;
869 static struct pipe_video_decoder
*
870 nvfx_context_create_decoder(struct pipe_context
*context
,
871 enum pipe_video_profile profile
,
872 enum pipe_video_entrypoint entrypoint
,
873 enum pipe_video_chroma_format chroma_format
,
874 unsigned width
, unsigned height
,
875 unsigned max_references
, bool expect_chunked_decode
)
877 struct nouveau_screen
*screen
= &nvfx_context(context
)->screen
->base
;
878 return nouveau_create_decoder(context
, screen
, profile
, entrypoint
,
879 chroma_format
, width
, height
,
880 max_references
, expect_chunked_decode
);
883 static struct pipe_video_buffer
*
884 nvfx_context_video_buffer_create(struct pipe_context
*pipe
,
885 enum pipe_format buffer_format
,
886 enum pipe_video_chroma_format chroma_format
,
887 unsigned width
, unsigned height
)
889 struct nouveau_screen
*screen
= &nvfx_context(pipe
)->screen
->base
;
890 return nouveau_video_buffer_create(pipe
, screen
, buffer_format
, chroma_format
, width
, height
);
894 nvfx_context_init_vdec(struct nvfx_context
*nv
)
896 nv
->pipe
.create_video_decoder
= nvfx_context_create_decoder
;
897 nv
->pipe
.create_video_buffer
= nvfx_context_video_buffer_create
;
900 static struct pipe_video_decoder
*
901 nouveau_context_create_decoder(struct pipe_context
*context
,
902 enum pipe_video_profile profile
,
903 enum pipe_video_entrypoint entrypoint
,
904 enum pipe_video_chroma_format chroma_format
,
905 unsigned width
, unsigned height
,
906 unsigned max_references
, bool expect_chunked_decode
)
908 struct nouveau_screen
*screen
= nouveau_context(context
)->screen
;
909 return nouveau_create_decoder(context
, screen
, profile
, entrypoint
,
910 chroma_format
, width
, height
,
911 max_references
, expect_chunked_decode
);
914 static struct pipe_video_buffer
*
915 nouveau_context_video_buffer_create(struct pipe_context
*pipe
,
916 enum pipe_format buffer_format
,
917 enum pipe_video_chroma_format chroma_format
,
918 unsigned width
, unsigned height
)
920 struct nouveau_screen
*screen
= nouveau_context(pipe
)->screen
;
921 return nouveau_video_buffer_create(pipe
, screen
, buffer_format
, chroma_format
, width
, height
);
925 nouveau_context_init_vdec(struct nouveau_context
*nv
)
927 nv
->pipe
.create_video_decoder
= nouveau_context_create_decoder
;
928 nv
->pipe
.create_video_buffer
= nouveau_context_video_buffer_create
;