2 * Copyright 2011-2013 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 "nvc0_video.h"
25 #include "util/u_sampler.h"
26 #include "util/u_format.h"
32 nvc0_screen_get_video_param(struct pipe_screen
*pscreen
,
33 enum pipe_video_profile profile
,
34 enum pipe_video_cap param
)
37 case PIPE_VIDEO_CAP_SUPPORTED
:
38 return profile
>= PIPE_VIDEO_PROFILE_MPEG1
;
39 case PIPE_VIDEO_CAP_NPOT_TEXTURES
:
41 case PIPE_VIDEO_CAP_MAX_WIDTH
:
42 case PIPE_VIDEO_CAP_MAX_HEIGHT
:
43 return nouveau_screen(pscreen
)->device
->chipset
< 0xd0 ? 2048 : 4096;
44 case PIPE_VIDEO_CAP_PREFERED_FORMAT
:
45 return PIPE_FORMAT_NV12
;
46 case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED
:
47 case PIPE_VIDEO_CAP_PREFERS_INTERLACED
:
49 case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE
:
51 case PIPE_VIDEO_CAP_MAX_LEVEL
:
53 case PIPE_VIDEO_PROFILE_MPEG1
:
55 case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE
:
56 case PIPE_VIDEO_PROFILE_MPEG2_MAIN
:
58 case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE
:
60 case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE
:
62 case PIPE_VIDEO_PROFILE_VC1_SIMPLE
:
64 case PIPE_VIDEO_PROFILE_VC1_MAIN
:
66 case PIPE_VIDEO_PROFILE_VC1_ADVANCED
:
68 case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE
:
69 case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN
:
70 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH
:
73 debug_printf("unknown video profile: %d\n", profile
);
77 debug_printf("unknown video param: %d\n", param
);
83 nvc0_decoder_decode_bitstream(struct pipe_video_decoder
*decoder
,
84 struct pipe_video_buffer
*video_target
,
85 struct pipe_picture_desc
*picture
,
87 const void *const *data
,
88 const unsigned *num_bytes
)
90 struct nvc0_decoder
*dec
= (struct nvc0_decoder
*)decoder
;
91 struct nouveau_vp3_video_buffer
*target
= (struct nouveau_vp3_video_buffer
*)video_target
;
92 uint32_t comm_seq
= ++dec
->fence_seq
;
95 unsigned vp_caps
, is_ref
, ret
;
96 struct nouveau_vp3_video_buffer
*refs
[16] = {};
100 assert(target
->base
.buffer_format
== PIPE_FORMAT_NV12
);
102 ret
= nvc0_decoder_bsp(dec
, desc
, target
, comm_seq
,
103 num_buffers
, data
, num_bytes
,
104 &vp_caps
, &is_ref
, refs
);
106 /* did we decode bitstream correctly? */
109 nvc0_decoder_vp(dec
, desc
, target
, comm_seq
, vp_caps
, is_ref
, refs
);
110 nvc0_decoder_ppp(dec
, desc
, target
, comm_seq
);
114 nvc0_decoder_flush(struct pipe_video_decoder
*decoder
)
116 struct nvc0_decoder
*dec
= (struct nvc0_decoder
*)decoder
;
121 nvc0_decoder_begin_frame(struct pipe_video_decoder
*decoder
,
122 struct pipe_video_buffer
*target
,
123 struct pipe_picture_desc
*picture
)
128 nvc0_decoder_end_frame(struct pipe_video_decoder
*decoder
,
129 struct pipe_video_buffer
*target
,
130 struct pipe_picture_desc
*picture
)
135 nvc0_decoder_destroy(struct pipe_video_decoder
*decoder
)
137 struct nvc0_decoder
*dec
= (struct nvc0_decoder
*)decoder
;
140 nouveau_bo_ref(NULL
, &dec
->ref_bo
);
141 nouveau_bo_ref(NULL
, &dec
->bitplane_bo
);
142 nouveau_bo_ref(NULL
, &dec
->inter_bo
[0]);
143 nouveau_bo_ref(NULL
, &dec
->inter_bo
[1]);
144 #ifdef NVC0_DEBUG_FENCE
145 nouveau_bo_ref(NULL
, &dec
->fence_bo
);
147 nouveau_bo_ref(NULL
, &dec
->fw_bo
);
149 for (i
= 0; i
< NVC0_VIDEO_QDEPTH
; ++i
)
150 nouveau_bo_ref(NULL
, &dec
->bsp_bo
[i
]);
152 nouveau_object_del(&dec
->bsp
);
153 nouveau_object_del(&dec
->vp
);
154 nouveau_object_del(&dec
->ppp
);
156 if (dec
->channel
[0] != dec
->channel
[1]) {
157 for (i
= 0; i
< 3; ++i
) {
158 nouveau_pushbuf_del(&dec
->pushbuf
[i
]);
159 nouveau_object_del(&dec
->channel
[i
]);
162 nouveau_pushbuf_del(dec
->pushbuf
);
163 nouveau_object_del(dec
->channel
);
169 static void nvc0_video_getpath(enum pipe_video_profile profile
, char *path
)
171 switch (u_reduce_video_profile(profile
)) {
172 case PIPE_VIDEO_CODEC_MPEG12
: {
173 sprintf(path
, "/lib/firmware/nouveau/vuc-mpeg12-0");
176 case PIPE_VIDEO_CODEC_MPEG4
: {
177 sprintf(path
, "/lib/firmware/nouveau/vuc-mpeg4-0");
180 case PIPE_VIDEO_CODEC_VC1
: {
181 sprintf(path
, "/lib/firmware/nouveau/vuc-vc1-0");
184 case PIPE_VIDEO_CODEC_MPEG4_AVC
: {
185 sprintf(path
, "/lib/firmware/nouveau/vuc-h264-0");
192 struct pipe_video_decoder
*
193 nvc0_create_decoder(struct pipe_context
*context
,
194 enum pipe_video_profile profile
,
195 enum pipe_video_entrypoint entrypoint
,
196 enum pipe_video_chroma_format chroma_format
,
197 unsigned width
, unsigned height
, unsigned max_references
,
200 struct nouveau_screen
*screen
= &((struct nvc0_context
*)context
)->screen
->base
;
201 struct nvc0_decoder
*dec
;
202 struct nouveau_pushbuf
**push
;
203 union nouveau_bo_config cfg
;
204 bool kepler
= screen
->device
->chipset
>= 0xe0;
206 cfg
.nvc0
.tile_mode
= 0x10;
207 cfg
.nvc0
.memtype
= 0xfe;
210 uint32_t codec
= 1, ppp_codec
= 3;
214 if (getenv("XVMC_VL"))
215 return vl_create_decoder(context
, profile
, entrypoint
,
216 chroma_format
, width
, height
,
217 max_references
, chunked_decode
);
219 if (entrypoint
!= PIPE_VIDEO_ENTRYPOINT_BITSTREAM
) {
220 debug_printf("%x\n", entrypoint
);
224 dec
= CALLOC_STRUCT(nvc0_decoder
);
227 dec
->client
= screen
->client
;
239 for (i
= 0; i
< 3; ++i
)
241 dec
->channel
[i
] = dec
->channel
[0];
242 dec
->pushbuf
[i
] = dec
->pushbuf
[0];
246 struct nvc0_fifo nvc0_args
= {};
247 struct nve0_fifo nve0_args
= {};
250 size
= sizeof(nvc0_args
);
253 unsigned engine
[] = {
254 NVE0_FIFO_ENGINE_BSP
,
259 nve0_args
.engine
= engine
[i
];
260 size
= sizeof(nve0_args
);
264 ret
= nouveau_object_new(&screen
->device
->object
, 0,
265 NOUVEAU_FIFO_CHANNEL_CLASS
,
266 data
, size
, &dec
->channel
[i
]);
269 ret
= nouveau_pushbuf_new(screen
->client
, dec
->channel
[i
], 4,
270 32 * 1024, true, &dec
->pushbuf
[i
]);
278 ret
= nouveau_object_new(dec
->channel
[0], 0x390b1, 0x90b1, NULL
, 0, &dec
->bsp
);
280 ret
= nouveau_object_new(dec
->channel
[1], 0x190b2, 0x90b2, NULL
, 0, &dec
->vp
);
282 ret
= nouveau_object_new(dec
->channel
[2], 0x290b3, 0x90b3, NULL
, 0, &dec
->ppp
);
285 ret
= nouveau_object_new(dec
->channel
[0], 0x95b1, 0x95b1, NULL
, 0, &dec
->bsp
);
287 ret
= nouveau_object_new(dec
->channel
[1], 0x95b2, 0x95b2, NULL
, 0, &dec
->vp
);
289 ret
= nouveau_object_new(dec
->channel
[2], 0x90b3, 0x90b3, NULL
, 0, &dec
->ppp
);
294 BEGIN_NVC0(push
[0], SUBC_BSP(NV01_SUBCHAN_OBJECT
), 1);
295 PUSH_DATA (push
[0], dec
->bsp
->handle
);
297 BEGIN_NVC0(push
[1], SUBC_VP(NV01_SUBCHAN_OBJECT
), 1);
298 PUSH_DATA (push
[1], dec
->vp
->handle
);
300 BEGIN_NVC0(push
[2], SUBC_PPP(NV01_SUBCHAN_OBJECT
), 1);
301 PUSH_DATA (push
[2], dec
->ppp
->handle
);
303 dec
->base
.context
= context
;
304 dec
->base
.profile
= profile
;
305 dec
->base
.entrypoint
= entrypoint
;
306 dec
->base
.chroma_format
= chroma_format
;
307 dec
->base
.width
= width
;
308 dec
->base
.height
= height
;
309 dec
->base
.max_references
= max_references
;
310 dec
->base
.destroy
= nvc0_decoder_destroy
;
311 dec
->base
.flush
= nvc0_decoder_flush
;
312 dec
->base
.decode_bitstream
= nvc0_decoder_decode_bitstream
;
313 dec
->base
.begin_frame
= nvc0_decoder_begin_frame
;
314 dec
->base
.end_frame
= nvc0_decoder_end_frame
;
316 for (i
= 0; i
< NVC0_VIDEO_QDEPTH
&& !ret
; ++i
)
317 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_VRAM
,
318 0, 1 << 20, &cfg
, &dec
->bsp_bo
[i
]);
320 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_VRAM
,
321 0x100, 4 << 20, &cfg
, &dec
->inter_bo
[0]);
324 nouveau_bo_ref(dec
->inter_bo
[0], &dec
->inter_bo
[1]);
326 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_VRAM
,
327 0x100, dec
->inter_bo
[0]->size
, &cfg
,
333 switch (u_reduce_video_profile(profile
)) {
334 case PIPE_VIDEO_CODEC_MPEG12
: {
336 assert(max_references
<= 2);
339 case PIPE_VIDEO_CODEC_MPEG4
: {
341 tmp_size
= mb(height
)*16 * mb(width
)*16;
342 assert(max_references
<= 2);
345 case PIPE_VIDEO_CODEC_VC1
: {
346 ppp_codec
= codec
= 2;
347 tmp_size
= mb(height
)*16 * mb(width
)*16;
348 assert(max_references
<= 2);
351 case PIPE_VIDEO_CODEC_MPEG4_AVC
: {
353 dec
->tmp_stride
= 16 * mb_half(width
) * nvc0_video_align(height
) * 3 / 2;
354 tmp_size
= dec
->tmp_stride
* (max_references
+ 1);
355 assert(max_references
<= 16);
359 fprintf(stderr
, "invalid codec\n");
363 if (screen
->device
->chipset
< 0xd0) {
367 uint32_t *end
, endval
;
369 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_VRAM
, 0,
370 0x4000, &cfg
, &dec
->fw_bo
);
372 ret
= nouveau_bo_map(dec
->fw_bo
, NOUVEAU_BO_WR
, dec
->client
);
376 nvc0_video_getpath(profile
, path
);
378 fd
= open(path
, O_RDONLY
| O_CLOEXEC
);
380 fprintf(stderr
, "opening firmware file %s failed: %m\n", path
);
383 r
= read(fd
, dec
->fw_bo
->map
, 0x4000);
387 fprintf(stderr
, "reading firmware file %s failed: %m\n", path
);
392 fprintf(stderr
, "firmware file %s too large!\n", path
);
397 fprintf(stderr
, "firmware file %s wrong size!\n", path
);
401 end
= dec
->fw_bo
->map
+ r
- 4;
403 while (endval
== *end
)
406 r
= (intptr_t)end
- (intptr_t)dec
->fw_bo
->map
+ 4;
408 switch (u_reduce_video_profile(profile
)) {
409 case PIPE_VIDEO_CODEC_MPEG12
: {
410 assert((r
& 0xff) == 0xe0);
411 dec
->fw_sizes
= (0x2e0<<16) | (r
- 0x2e0);
414 case PIPE_VIDEO_CODEC_MPEG4
: {
415 assert((r
& 0xff) == 0xe0);
416 dec
->fw_sizes
= (0x2e0<<16) | (r
- 0x2e0);
419 case PIPE_VIDEO_CODEC_VC1
: {
420 assert((r
& 0xff) == 0xac);
421 dec
->fw_sizes
= (0x3ac<<16) | (r
- 0x3ac);
424 case PIPE_VIDEO_CODEC_MPEG4_AVC
: {
425 assert((r
& 0xff) == 0x70);
426 dec
->fw_sizes
= (0x370<<16) | (r
- 0x370);
432 munmap(dec
->fw_bo
->map
, dec
->fw_bo
->size
);
433 dec
->fw_bo
->map
= NULL
;
437 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_VRAM
, 0,
438 0x400, &cfg
, &dec
->bitplane_bo
);
443 dec
->ref_stride
= mb(width
)*16 * (mb_half(height
)*32 + nvc0_video_align(height
)/2);
444 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_VRAM
, 0,
445 dec
->ref_stride
* (max_references
+2) + tmp_size
,
452 BEGIN_NVC0(push
[0], SUBC_BSP(0x200), 2);
453 PUSH_DATA (push
[0], codec
);
454 PUSH_DATA (push
[0], timeout
);
456 BEGIN_NVC0(push
[1], SUBC_VP(0x200), 2);
457 PUSH_DATA (push
[1], codec
);
458 PUSH_DATA (push
[1], timeout
);
460 BEGIN_NVC0(push
[2], SUBC_PPP(0x200), 2);
461 PUSH_DATA (push
[2], ppp_codec
);
462 PUSH_DATA (push
[2], timeout
);
467 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_GART
|NOUVEAU_BO_MAP
,
468 0, 0x1000, NULL
, &dec
->fence_bo
);
472 nouveau_bo_map(dec
->fence_bo
, NOUVEAU_BO_RDWR
, screen
->client
);
473 dec
->fence_map
= dec
->fence_bo
->map
;
474 dec
->fence_map
[0] = dec
->fence_map
[4] = dec
->fence_map
[8] = 0;
475 dec
->comm
= (struct comm
*)(dec
->fence_map
+ (COMM_OFFSET
/sizeof(*dec
->fence_map
)));
477 /* So lets test if the fence is working? */
478 nouveau_pushbuf_space(push
[0], 6, 1, 0);
479 PUSH_REFN (push
[0], dec
->fence_bo
, NOUVEAU_BO_GART
|NOUVEAU_BO_RDWR
);
480 BEGIN_NVC0(push
[0], SUBC_BSP(0x240), 3);
481 PUSH_DATAh(push
[0], dec
->fence_bo
->offset
);
482 PUSH_DATA (push
[0], dec
->fence_bo
->offset
);
483 PUSH_DATA (push
[0], dec
->fence_seq
);
485 BEGIN_NVC0(push
[0], SUBC_BSP(0x304), 1);
486 PUSH_DATA (push
[0], 0);
489 nouveau_pushbuf_space(push
[1], 6, 1, 0);
490 PUSH_REFN (push
[1], dec
->fence_bo
, NOUVEAU_BO_GART
|NOUVEAU_BO_RDWR
);
491 BEGIN_NVC0(push
[1], SUBC_VP(0x240), 3);
492 PUSH_DATAh(push
[1], (dec
->fence_bo
->offset
+ 0x10));
493 PUSH_DATA (push
[1], (dec
->fence_bo
->offset
+ 0x10));
494 PUSH_DATA (push
[1], dec
->fence_seq
);
496 BEGIN_NVC0(push
[1], SUBC_VP(0x304), 1);
497 PUSH_DATA (push
[1], 0);
500 nouveau_pushbuf_space(push
[2], 6, 1, 0);
501 PUSH_REFN (push
[2], dec
->fence_bo
, NOUVEAU_BO_GART
|NOUVEAU_BO_RDWR
);
502 BEGIN_NVC0(push
[2], SUBC_PPP(0x240), 3);
503 PUSH_DATAh(push
[2], (dec
->fence_bo
->offset
+ 0x20));
504 PUSH_DATA (push
[2], (dec
->fence_bo
->offset
+ 0x20));
505 PUSH_DATA (push
[2], dec
->fence_seq
);
507 BEGIN_NVC0(push
[2], SUBC_PPP(0x304), 1);
508 PUSH_DATA (push
[2], 0);
512 while (dec
->fence_seq
> dec
->fence_map
[0] ||
513 dec
->fence_seq
> dec
->fence_map
[4] ||
514 dec
->fence_seq
> dec
->fence_map
[8]) {
515 debug_printf("%u: %u %u %u\n", dec
->fence_seq
, dec
->fence_map
[0], dec
->fence_map
[4], dec
->fence_map
[8]);
518 debug_printf("%u: %u %u %u\n", dec
->fence_seq
, dec
->fence_map
[0], dec
->fence_map
[4], dec
->fence_map
[8]);
524 debug_printf("Cannot create decoder without firmware..\n");
525 nvc0_decoder_destroy(&dec
->base
);
529 debug_printf("Creation failed: %s (%i)\n", strerror(-ret
), ret
);
530 nvc0_decoder_destroy(&dec
->base
);
534 struct pipe_video_buffer
*
535 nvc0_video_buffer_create(struct pipe_context
*pipe
,
536 const struct pipe_video_buffer
*templat
)
538 return nouveau_vp3_video_buffer_create(
539 pipe
, templat
, NVC0_RESOURCE_FLAG_VIDEO
);