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_begin_frame(struct pipe_video_decoder
*decoder
,
428 struct pipe_video_buffer
*target
,
429 struct pipe_picture_desc
*picture
)
434 nouveau_decoder_decode_macroblock(struct pipe_video_decoder
*decoder
,
435 struct pipe_video_buffer
*target
,
436 struct pipe_picture_desc
*picture
,
437 const struct pipe_macroblock
*pipe_mb
,
438 unsigned num_macroblocks
)
440 struct nouveau_decoder
*dec
= (struct nouveau_decoder
*)decoder
;
441 struct pipe_mpeg12_picture_desc
*desc
= (struct pipe_mpeg12_picture_desc
*)picture
;
442 const struct pipe_mpeg12_macroblock
*mb
;
444 assert(target
->width
== decoder
->width
);
445 assert(target
->height
== decoder
->height
);
447 dec
->current
= nouveau_decoder_surface_index(dec
, target
);
448 assert(dec
->current
< 8);
449 dec
->picture_structure
= desc
->picture_structure
;
451 dec
->future
= nouveau_decoder_surface_index(dec
, desc
->ref
[1]);
453 dec
->past
= nouveau_decoder_surface_index(dec
, desc
->ref
[0]);
455 if (nouveau_vpe_init(dec
)) return;
456 mb
= (const struct pipe_mpeg12_macroblock
*)pipe_mb
;
457 for (i
= 0; i
< num_macroblocks
; ++i
, mb
++) {
458 if (mb
->macroblock_type
& PIPE_MPEG12_MB_TYPE_INTRA
) {
459 nouveau_vpe_mb_dct_header(dec
, mb
, TRUE
);
460 nouveau_vpe_mb_dct_header(dec
, mb
, FALSE
);
462 nouveau_vpe_mb_mv_header(dec
, mb
, TRUE
);
463 nouveau_vpe_mb_dct_header(dec
, mb
, TRUE
);
465 nouveau_vpe_mb_mv_header(dec
, mb
, FALSE
);
466 nouveau_vpe_mb_dct_header(dec
, mb
, FALSE
);
468 if (dec
->base
.entrypoint
<= PIPE_VIDEO_ENTRYPOINT_IDCT
)
469 nouveau_vpe_mb_dct_blocks(dec
, mb
);
471 nouveau_vpe_mb_data_blocks(dec
, mb
);
476 nouveau_decoder_end_frame(struct pipe_video_decoder
*decoder
,
477 struct pipe_video_buffer
*target
,
478 struct pipe_picture_desc
*picture
)
483 nouveau_decoder_flush(struct pipe_video_decoder
*decoder
)
485 struct nouveau_decoder
*dec
= (struct nouveau_decoder
*)decoder
;
487 nouveau_vpe_fini(dec
);
491 nouveau_decoder_destroy(struct pipe_video_decoder
*decoder
)
493 struct nouveau_decoder
*dec
= (struct nouveau_decoder
*)decoder
;
496 nouveau_bo_unmap(dec
->data_bo
);
497 nouveau_bo_unmap(dec
->cmd_bo
);
501 nouveau_bo_ref(NULL
, &dec
->data_bo
);
503 nouveau_bo_ref(NULL
, &dec
->cmd_bo
);
505 nouveau_bo_ref(NULL
, &dec
->fence_bo
);
506 nouveau_grobj_free(&dec
->mpeg
);
510 static struct pipe_video_decoder
*
511 nouveau_create_decoder(struct pipe_context
*context
,
512 struct nouveau_screen
*screen
,
513 enum pipe_video_profile profile
,
514 enum pipe_video_entrypoint entrypoint
,
515 enum pipe_video_chroma_format chroma_format
,
516 unsigned width
, unsigned height
,
517 unsigned max_references
, bool expect_chunked_decode
)
519 struct nouveau_channel
*chan
= screen
->channel
;
520 struct nouveau_grobj
*mpeg
= NULL
;
521 struct nouveau_decoder
*dec
;
523 bool is8274
= screen
->device
->chipset
> 0x80;
525 debug_printf("Acceleration level: %s\n", entrypoint
<= PIPE_VIDEO_ENTRYPOINT_BITSTREAM
? "bit":
526 entrypoint
== PIPE_VIDEO_ENTRYPOINT_IDCT
? "IDCT" : "MC");
528 if (getenv("XVMC_VL"))
530 if (u_reduce_video_profile(profile
) != PIPE_VIDEO_CODEC_MPEG12
)
532 if (screen
->device
->chipset
>= 0x98 && screen
->device
->chipset
!= 0xa0)
535 width
= align(width
, 64);
536 height
= align(height
, 64);
539 ret
= nouveau_grobj_alloc(chan
, 0xbeef8274, 0x8274, &mpeg
);
541 ret
= nouveau_grobj_alloc(chan
, 0xbeef8274, 0x3174, &mpeg
);
543 debug_printf("Creation failed: %s (%i)\n", strerror(-ret
), ret
);
547 dec
= CALLOC_STRUCT(nouveau_decoder
);
549 nouveau_grobj_free(&mpeg
);
553 dec
->base
.context
= context
;
554 dec
->base
.profile
= profile
;
555 dec
->base
.entrypoint
= entrypoint
;
556 dec
->base
.chroma_format
= chroma_format
;
557 dec
->base
.width
= width
;
558 dec
->base
.height
= height
;
559 dec
->base
.max_references
= max_references
;
560 dec
->base
.destroy
= nouveau_decoder_destroy
;
561 dec
->base
.begin_frame
= nouveau_decoder_begin_frame
;
562 dec
->base
.decode_macroblock
= nouveau_decoder_decode_macroblock
;
563 dec
->base
.begin_frame
= nouveau_decoder_end_frame
;
564 dec
->base
.flush
= nouveau_decoder_flush
;
565 dec
->screen
= screen
;
567 ret
= nouveau_bo_new(dec
->screen
->device
, NOUVEAU_BO_GART
, 0, 1024 * 1024, &dec
->cmd_bo
);
571 ret
= nouveau_bo_new(dec
->screen
->device
, NOUVEAU_BO_GART
, 0, width
* height
* 6, &dec
->data_bo
);
575 ret
= nouveau_bo_new(dec
->screen
->device
, NOUVEAU_BO_GART
|NOUVEAU_BO_MAP
, 0, 4096,
579 nouveau_bo_map(dec
->fence_bo
, NOUVEAU_BO_RDWR
);
580 dec
->fence_map
= dec
->fence_bo
->map
;
581 nouveau_bo_unmap(dec
->fence_bo
);
582 dec
->fence_map
[0] = 0;
585 MARK_RING(chan
, 25, 3);
587 MARK_RING(chan
, 20, 2);
589 BEGIN_RING(chan
, mpeg
, NV31_MPEG_DMA_CMD
, 1);
590 OUT_RING(chan
, chan
->vram
->handle
);
592 BEGIN_RING(chan
, mpeg
, NV31_MPEG_DMA_DATA
, 1);
593 OUT_RING(chan
, chan
->vram
->handle
);
595 BEGIN_RING(chan
, mpeg
, NV31_MPEG_DMA_IMAGE
, 1);
596 OUT_RING(chan
, chan
->vram
->handle
);
598 BEGIN_RING(chan
, mpeg
, NV31_MPEG_PITCH
, 2);
599 OUT_RING(chan
, width
| NV31_MPEG_PITCH_UNK
);
600 OUT_RING(chan
, (height
<< NV31_MPEG_SIZE_H__SHIFT
) | width
);
602 BEGIN_RING(chan
, mpeg
, NV31_MPEG_FORMAT
, 2);
604 switch (entrypoint
) {
605 case PIPE_VIDEO_ENTRYPOINT_BITSTREAM
: OUT_RING(chan
, 0x100); break;
606 case PIPE_VIDEO_ENTRYPOINT_IDCT
: OUT_RING(chan
, 1); break;
607 case PIPE_VIDEO_ENTRYPOINT_MC
: OUT_RING(chan
, 0); break;
612 BEGIN_RING(chan
, mpeg
, NV84_MPEG_DMA_QUERY
, 1);
613 OUT_RING(chan
, chan
->vram
->handle
);
615 BEGIN_RING(chan
, mpeg
, NV84_MPEG_QUERY_OFFSET
, 2);
616 OUT_RELOCl(chan
, dec
->fence_bo
, 0, NOUVEAU_BO_WR
|NOUVEAU_BO_GART
);
617 OUT_RING(chan
, dec
->fence_seq
);
620 ret
= nouveau_vpe_init(dec
);
623 nouveau_vpe_fini(dec
);
627 nouveau_decoder_destroy(&dec
->base
);
631 debug_printf("Using g3dvl renderer\n");
632 return vl_create_decoder(context
, profile
, entrypoint
,
633 chroma_format
, width
, height
,
634 max_references
, expect_chunked_decode
);
637 static struct pipe_sampler_view
**
638 nouveau_video_buffer_sampler_view_planes(struct pipe_video_buffer
*buffer
)
640 struct nouveau_video_buffer
*buf
= (struct nouveau_video_buffer
*)buffer
;
641 struct pipe_sampler_view sv_templ
;
642 struct pipe_context
*pipe
;
647 pipe
= buf
->base
.context
;
649 for (i
= 0; i
< buf
->num_planes
; ++i
) {
650 if (!buf
->sampler_view_planes
[i
]) {
651 memset(&sv_templ
, 0, sizeof(sv_templ
));
652 u_sampler_view_default_template(&sv_templ
, buf
->resources
[i
], buf
->resources
[i
]->format
);
654 if (util_format_get_nr_components(buf
->resources
[i
]->format
) == 1)
655 sv_templ
.swizzle_r
= sv_templ
.swizzle_g
= sv_templ
.swizzle_b
= sv_templ
.swizzle_a
= PIPE_SWIZZLE_RED
;
657 buf
->sampler_view_planes
[i
] = pipe
->create_sampler_view(pipe
, buf
->resources
[i
], &sv_templ
);
658 if (!buf
->sampler_view_planes
[i
])
663 return buf
->sampler_view_planes
;
666 for (i
= 0; i
< buf
->num_planes
; ++i
)
667 pipe_sampler_view_reference(&buf
->sampler_view_planes
[i
], NULL
);
672 static struct pipe_sampler_view
**
673 nouveau_video_buffer_sampler_view_components(struct pipe_video_buffer
*buffer
)
675 struct nouveau_video_buffer
*buf
= (struct nouveau_video_buffer
*)buffer
;
676 struct pipe_sampler_view sv_templ
;
677 struct pipe_context
*pipe
;
678 unsigned i
, j
, component
;
682 pipe
= buf
->base
.context
;
684 for (component
= 0, i
= 0; i
< buf
->num_planes
; ++i
) {
685 unsigned nr_components
= util_format_get_nr_components(buf
->resources
[i
]->format
);
687 for (j
= 0; j
< nr_components
; ++j
, ++component
) {
688 assert(component
< VL_MAX_PLANES
);
690 if (!buf
->sampler_view_components
[component
]) {
691 memset(&sv_templ
, 0, sizeof(sv_templ
));
692 u_sampler_view_default_template(&sv_templ
, buf
->resources
[i
], buf
->resources
[i
]->format
);
693 sv_templ
.swizzle_r
= sv_templ
.swizzle_g
= sv_templ
.swizzle_b
= PIPE_SWIZZLE_RED
+ j
;
694 sv_templ
.swizzle_a
= PIPE_SWIZZLE_ONE
;
695 buf
->sampler_view_components
[component
] = pipe
->create_sampler_view(pipe
, buf
->resources
[i
], &sv_templ
);
696 if (!buf
->sampler_view_components
[component
])
702 return buf
->sampler_view_components
;
705 for (i
= 0; i
< 3; ++i
)
706 pipe_sampler_view_reference(&buf
->sampler_view_components
[i
], NULL
);
711 static struct pipe_surface
**
712 nouveau_video_buffer_surfaces(struct pipe_video_buffer
*buffer
)
714 struct nouveau_video_buffer
*buf
= (struct nouveau_video_buffer
*)buffer
;
715 struct pipe_surface surf_templ
;
716 struct pipe_context
*pipe
;
721 pipe
= buf
->base
.context
;
723 for (i
= 0; i
< buf
->num_planes
; ++i
) {
724 if (!buf
->surfaces
[i
]) {
725 memset(&surf_templ
, 0, sizeof(surf_templ
));
726 surf_templ
.format
= buf
->resources
[i
]->format
;
727 surf_templ
.usage
= PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
;
728 buf
->surfaces
[i
] = pipe
->create_surface(pipe
, buf
->resources
[i
], &surf_templ
);
729 if (!buf
->surfaces
[i
])
734 return buf
->surfaces
;
737 for (i
= 0; i
< buf
->num_planes
; ++i
)
738 pipe_surface_reference(&buf
->surfaces
[i
], NULL
);
744 nouveau_video_buffer_destroy(struct pipe_video_buffer
*buffer
)
746 struct nouveau_video_buffer
*buf
= (struct nouveau_video_buffer
*)buffer
;
751 for (i
= 0; i
< buf
->num_planes
; ++i
) {
752 pipe_surface_reference(&buf
->surfaces
[i
], NULL
);
753 pipe_sampler_view_reference(&buf
->sampler_view_planes
[i
], NULL
);
754 pipe_sampler_view_reference(&buf
->sampler_view_components
[i
], NULL
);
755 pipe_resource_reference(&buf
->resources
[i
], NULL
);
758 pipe_sampler_view_reference(&buf
->sampler_view_components
[i
], NULL
);
763 static struct pipe_video_buffer
*
764 nouveau_video_buffer_create(struct pipe_context
*pipe
,
765 struct nouveau_screen
*screen
,
766 const struct pipe_video_buffer
*templat
)
768 struct nouveau_video_buffer
*buffer
;
769 struct pipe_resource templ
;
770 unsigned width
, height
;
772 /* Only do a linear surface when a hardware decoder is used
773 * hardware decoder is only supported on some chipsets
774 * and it only supports the NV12 format
776 if (templat
->buffer_format
!= PIPE_FORMAT_NV12
|| getenv("XVMC_VL") ||
777 (screen
->device
->chipset
>= 0x98 && screen
->device
->chipset
!= 0xa0))
778 return vl_video_buffer_create(pipe
, templat
);
780 assert(templat
->chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_420
);
781 width
= align(templat
->width
, 64);
782 height
= align(templat
->height
, 64);
784 buffer
= CALLOC_STRUCT(nouveau_video_buffer
);
788 buffer
->base
.context
= pipe
;
789 buffer
->base
.destroy
= nouveau_video_buffer_destroy
;
790 buffer
->base
.get_sampler_view_planes
= nouveau_video_buffer_sampler_view_planes
;
791 buffer
->base
.get_sampler_view_components
= nouveau_video_buffer_sampler_view_components
;
792 buffer
->base
.get_surfaces
= nouveau_video_buffer_surfaces
;
793 buffer
->base
.chroma_format
= templat
->chroma_format
;
794 buffer
->base
.width
= width
;
795 buffer
->base
.height
= height
;
796 buffer
->num_planes
= 2;
798 memset(&templ
, 0, sizeof(templ
));
799 templ
.target
= PIPE_TEXTURE_2D
;
800 templ
.format
= PIPE_FORMAT_R8_UNORM
;
801 templ
.width0
= width
;
802 templ
.height0
= height
;
804 templ
.array_size
= 1;
805 templ
.bind
= PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
;
806 templ
.usage
= PIPE_USAGE_STATIC
;
807 templ
.flags
= NOUVEAU_RESOURCE_FLAG_LINEAR
;
809 buffer
->resources
[0] = pipe
->screen
->resource_create(pipe
->screen
, &templ
);
810 if (!buffer
->resources
[0])
814 templ
.format
= PIPE_FORMAT_R8G8_UNORM
;
815 buffer
->resources
[1] = pipe
->screen
->resource_create(pipe
->screen
, &templ
);
816 if (!buffer
->resources
[1])
818 return &buffer
->base
;
821 nouveau_video_buffer_destroy(&buffer
->base
);
826 nouveau_screen_get_video_param(struct pipe_screen
*pscreen
,
827 enum pipe_video_profile profile
,
828 enum pipe_video_cap param
)
831 case PIPE_VIDEO_CAP_SUPPORTED
:
832 return vl_profile_supported(pscreen
, profile
);
833 case PIPE_VIDEO_CAP_NPOT_TEXTURES
:
835 case PIPE_VIDEO_CAP_MAX_WIDTH
:
836 case PIPE_VIDEO_CAP_MAX_HEIGHT
:
837 return vl_video_buffer_max_size(pscreen
);
839 debug_printf("unknown video param: %d\n", param
);
845 nouveau_screen_init_vdec(struct nouveau_screen
*screen
)
847 screen
->base
.get_video_param
= nouveau_screen_get_video_param
;
848 screen
->base
.is_video_format_supported
= vl_video_buffer_is_format_supported
;
851 static struct pipe_video_decoder
*
852 nvfx_context_create_decoder(struct pipe_context
*context
,
853 enum pipe_video_profile profile
,
854 enum pipe_video_entrypoint entrypoint
,
855 enum pipe_video_chroma_format chroma_format
,
856 unsigned width
, unsigned height
,
857 unsigned max_references
, bool expect_chunked_decode
)
859 struct nouveau_screen
*screen
= &nvfx_context(context
)->screen
->base
;
860 return nouveau_create_decoder(context
, screen
, profile
, entrypoint
,
861 chroma_format
, width
, height
,
862 max_references
, expect_chunked_decode
);
865 static struct pipe_video_buffer
*
866 nvfx_context_video_buffer_create(struct pipe_context
*pipe
,
867 const struct pipe_video_buffer
*templat
)
869 struct nouveau_screen
*screen
= &nvfx_context(pipe
)->screen
->base
;
870 return nouveau_video_buffer_create(pipe
, screen
, templat
);
874 nvfx_context_init_vdec(struct nvfx_context
*nv
)
876 nv
->pipe
.create_video_decoder
= nvfx_context_create_decoder
;
877 nv
->pipe
.create_video_buffer
= nvfx_context_video_buffer_create
;
880 static struct pipe_video_decoder
*
881 nouveau_context_create_decoder(struct pipe_context
*context
,
882 enum pipe_video_profile profile
,
883 enum pipe_video_entrypoint entrypoint
,
884 enum pipe_video_chroma_format chroma_format
,
885 unsigned width
, unsigned height
,
886 unsigned max_references
, bool expect_chunked_decode
)
888 struct nouveau_screen
*screen
= nouveau_context(context
)->screen
;
889 return nouveau_create_decoder(context
, screen
, profile
, entrypoint
,
890 chroma_format
, width
, height
,
891 max_references
, expect_chunked_decode
);
894 static struct pipe_video_buffer
*
895 nouveau_context_video_buffer_create(struct pipe_context
*pipe
,
896 const struct pipe_video_buffer
*templat
)
898 struct nouveau_screen
*screen
= nouveau_context(pipe
)->screen
;
899 return nouveau_video_buffer_create(pipe
, screen
, templat
);
903 nouveau_context_init_vdec(struct nouveau_context
*nv
)
905 nv
->pipe
.create_video_decoder
= nouveau_context_create_decoder
;
906 nv
->pipe
.create_video_buffer
= nouveau_context_video_buffer_create
;