2 * Copyright 2013 Ilia Mirkin
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.
25 #include <sys/types.h>
28 #include "util/u_format.h"
29 #include "util/u_sampler.h"
30 #include "vl/vl_zscan.h"
32 #include "nv50/nv84_video.h"
35 nv84_copy_firmware(const char *path
, void *dest
, ssize_t len
)
37 int fd
= open(path
, O_RDONLY
| O_CLOEXEC
);
40 fprintf(stderr
, "opening firmware file %s failed: %m\n", path
);
43 r
= read(fd
, dest
, len
);
47 fprintf(stderr
, "reading firwmare file %s failed: %m\n", path
);
55 filesize(const char *path
)
60 ret
= stat(path
, &statbuf
);
63 return statbuf
.st_size
;
66 static struct nouveau_bo
*
67 nv84_load_firmwares(struct nouveau_device
*dev
, struct nv84_decoder
*dec
,
68 const char *fw1
, const char *fw2
)
70 int ret
, size1
, size2
= 0;
71 struct nouveau_bo
*fw
;
73 size1
= filesize(fw1
);
75 size2
= filesize(fw2
);
76 if (size1
< 0 || size2
< 0)
79 dec
->vp_fw2_offset
= align(size1
, 0x100);
81 ret
= nouveau_bo_new(dev
, NOUVEAU_BO_VRAM
, 0, dec
->vp_fw2_offset
+ size2
, NULL
, &fw
);
84 ret
= nouveau_bo_map(fw
, NOUVEAU_BO_WR
, dec
->client
);
88 ret
= nv84_copy_firmware(fw1
, fw
->map
, size1
);
90 ret
= nv84_copy_firmware(fw2
, fw
->map
+ dec
->vp_fw2_offset
, size2
);
91 munmap(fw
->map
, fw
->size
);
96 nouveau_bo_ref(NULL
, &fw
);
100 static struct nouveau_bo
*
101 nv84_load_bsp_firmware(struct nouveau_device
*dev
, struct nv84_decoder
*dec
)
103 return nv84_load_firmwares(
104 dev
, dec
, "/lib/firmware/nouveau/nv84_bsp-h264", NULL
);
107 static struct nouveau_bo
*
108 nv84_load_vp_firmware(struct nouveau_device
*dev
, struct nv84_decoder
*dec
)
110 return nv84_load_firmwares(
112 "/lib/firmware/nouveau/nv84_vp-h264-1",
113 "/lib/firmware/nouveau/nv84_vp-h264-2");
116 static struct nouveau_bo
*
117 nv84_load_vp_firmware_mpeg(struct nouveau_device
*dev
, struct nv84_decoder
*dec
)
119 return nv84_load_firmwares(
120 dev
, dec
, "/lib/firmware/nouveau/nv84_vp-mpeg12", NULL
);
124 nv84_decoder_decode_bitstream_h264(struct pipe_video_codec
*decoder
,
125 struct pipe_video_buffer
*video_target
,
126 struct pipe_picture_desc
*picture
,
127 unsigned num_buffers
,
128 const void *const *data
,
129 const unsigned *num_bytes
)
131 struct nv84_decoder
*dec
= (struct nv84_decoder
*)decoder
;
132 struct nv84_video_buffer
*target
= (struct nv84_video_buffer
*)video_target
;
134 struct pipe_h264_picture_desc
*desc
= (struct pipe_h264_picture_desc
*)picture
;
136 assert(target
->base
.buffer_format
== PIPE_FORMAT_NV12
);
138 nv84_decoder_bsp(dec
, desc
, num_buffers
, data
, num_bytes
, target
);
139 nv84_decoder_vp_h264(dec
, desc
, target
);
143 nv84_decoder_flush(struct pipe_video_codec
*decoder
)
148 nv84_decoder_begin_frame_h264(struct pipe_video_codec
*decoder
,
149 struct pipe_video_buffer
*target
,
150 struct pipe_picture_desc
*picture
)
155 nv84_decoder_end_frame_h264(struct pipe_video_codec
*decoder
,
156 struct pipe_video_buffer
*target
,
157 struct pipe_picture_desc
*picture
)
162 nv84_decoder_decode_bitstream_mpeg12(struct pipe_video_codec
*decoder
,
163 struct pipe_video_buffer
*video_target
,
164 struct pipe_picture_desc
*picture
,
165 unsigned num_buffers
,
166 const void *const *data
,
167 const unsigned *num_bytes
)
169 struct nv84_decoder
*dec
= (struct nv84_decoder
*)decoder
;
171 assert(video_target
->buffer_format
== PIPE_FORMAT_NV12
);
173 vl_mpg12_bs_decode(dec
->mpeg12_bs
,
175 (struct pipe_mpeg12_picture_desc
*)picture
,
182 nv84_decoder_begin_frame_mpeg12(struct pipe_video_codec
*decoder
,
183 struct pipe_video_buffer
*target
,
184 struct pipe_picture_desc
*picture
)
186 struct nv84_decoder
*dec
= (struct nv84_decoder
*)decoder
;
187 struct pipe_mpeg12_picture_desc
*desc
= (struct pipe_mpeg12_picture_desc
*)picture
;
190 nouveau_bo_wait(dec
->mpeg12_bo
, NOUVEAU_BO_RDWR
, dec
->client
);
191 dec
->mpeg12_mb_info
= dec
->mpeg12_bo
->map
+ 0x100;
192 dec
->mpeg12_data
= dec
->mpeg12_bo
->map
+ 0x100 +
193 align(0x20 * mb(dec
->base
.width
) * mb(dec
->base
.height
), 0x100);
194 if (desc
->intra_matrix
) {
195 dec
->zscan
= desc
->alternate_scan
? vl_zscan_alternate
: vl_zscan_normal
;
196 for (i
= 0; i
< 64; i
++) {
197 dec
->mpeg12_intra_matrix
[i
] = desc
->intra_matrix
[dec
->zscan
[i
]];
198 dec
->mpeg12_non_intra_matrix
[i
] = desc
->non_intra_matrix
[dec
->zscan
[i
]];
200 dec
->mpeg12_intra_matrix
[0] = 1 << (7 - desc
->intra_dc_precision
);
205 nv84_decoder_end_frame_mpeg12(struct pipe_video_codec
*decoder
,
206 struct pipe_video_buffer
*target
,
207 struct pipe_picture_desc
*picture
)
209 nv84_decoder_vp_mpeg12(
210 (struct nv84_decoder
*)decoder
,
211 (struct pipe_mpeg12_picture_desc
*)picture
,
212 (struct nv84_video_buffer
*)target
);
216 nv84_decoder_decode_macroblock(struct pipe_video_codec
*decoder
,
217 struct pipe_video_buffer
*target
,
218 struct pipe_picture_desc
*picture
,
219 const struct pipe_macroblock
*macroblocks
,
220 unsigned num_macroblocks
)
222 const struct pipe_mpeg12_macroblock
*mb
= (const struct pipe_mpeg12_macroblock
*)macroblocks
;
223 for (int i
= 0; i
< num_macroblocks
; i
++, mb
++) {
224 nv84_decoder_vp_mpeg12_mb(
225 (struct nv84_decoder
*)decoder
,
226 (struct pipe_mpeg12_picture_desc
*)picture
,
232 nv84_decoder_destroy(struct pipe_video_codec
*decoder
)
234 struct nv84_decoder
*dec
= (struct nv84_decoder
*)decoder
;
236 nouveau_bo_ref(NULL
, &dec
->bsp_fw
);
237 nouveau_bo_ref(NULL
, &dec
->bsp_data
);
238 nouveau_bo_ref(NULL
, &dec
->vp_fw
);
239 nouveau_bo_ref(NULL
, &dec
->vp_data
);
240 nouveau_bo_ref(NULL
, &dec
->mbring
);
241 nouveau_bo_ref(NULL
, &dec
->vpring
);
242 nouveau_bo_ref(NULL
, &dec
->bitstream
);
243 nouveau_bo_ref(NULL
, &dec
->vp_params
);
244 nouveau_bo_ref(NULL
, &dec
->fence
);
246 nouveau_object_del(&dec
->bsp
);
247 nouveau_object_del(&dec
->vp
);
249 nouveau_bufctx_del(&dec
->bsp_bufctx
);
250 nouveau_pushbuf_del(&dec
->bsp_pushbuf
);
251 nouveau_object_del(&dec
->bsp_channel
);
253 nouveau_bufctx_del(&dec
->vp_bufctx
);
254 nouveau_pushbuf_del(&dec
->vp_pushbuf
);
255 nouveau_object_del(&dec
->vp_channel
);
257 nouveau_client_del(&dec
->client
);
260 FREE(dec
->mpeg12_bs
);
264 struct pipe_video_codec
*
265 nv84_create_decoder(struct pipe_context
*context
,
266 const struct pipe_video_codec
*templ
)
268 struct nv50_context
*nv50
= (struct nv50_context
*)context
;
269 struct nouveau_screen
*screen
= &nv50
->screen
->base
;
270 struct nv84_decoder
*dec
;
271 struct nouveau_pushbuf
*bsp_push
, *vp_push
;
272 struct nv50_surface surf
;
273 struct nv50_miptree mip
;
274 union pipe_color_union color
;
275 struct nv04_fifo nv04_data
= { .vram
= 0xbeef0201, .gart
= 0xbeef0202 };
277 int is_h264
= u_reduce_video_profile(templ
->profile
) == PIPE_VIDEO_FORMAT_MPEG4_AVC
;
278 int is_mpeg12
= u_reduce_video_profile(templ
->profile
) == PIPE_VIDEO_FORMAT_MPEG12
;
280 if (getenv("XVMC_VL"))
281 return vl_create_decoder(context
, templ
);
283 if ((is_h264
&& templ
->entrypoint
!= PIPE_VIDEO_ENTRYPOINT_BITSTREAM
) ||
284 (is_mpeg12
&& templ
->entrypoint
> PIPE_VIDEO_ENTRYPOINT_IDCT
)) {
285 debug_printf("%x\n", templ
->entrypoint
);
289 if (!is_h264
&& !is_mpeg12
) {
290 debug_printf("invalid profile: %x\n", templ
->profile
);
294 dec
= CALLOC_STRUCT(nv84_decoder
);
299 dec
->base
.context
= context
;
300 dec
->base
.destroy
= nv84_decoder_destroy
;
301 dec
->base
.flush
= nv84_decoder_flush
;
303 dec
->base
.decode_bitstream
= nv84_decoder_decode_bitstream_h264
;
304 dec
->base
.begin_frame
= nv84_decoder_begin_frame_h264
;
305 dec
->base
.end_frame
= nv84_decoder_end_frame_h264
;
307 dec
->frame_mbs
= mb(dec
->base
.width
) * mb_half(dec
->base
.height
) * 2;
308 dec
->frame_size
= dec
->frame_mbs
<< 8;
309 dec
->vpring_deblock
= align(0x30 * dec
->frame_mbs
, 0x100);
310 dec
->vpring_residual
= 0x2000 + MAX2(0x32000, 0x600 * dec
->frame_mbs
);
311 dec
->vpring_ctrl
= MAX2(0x10000, align(0x1080 + 0x144 * dec
->frame_mbs
, 0x100));
312 } else if (is_mpeg12
) {
313 dec
->base
.decode_macroblock
= nv84_decoder_decode_macroblock
;
314 dec
->base
.begin_frame
= nv84_decoder_begin_frame_mpeg12
;
315 dec
->base
.end_frame
= nv84_decoder_end_frame_mpeg12
;
317 if (templ
->entrypoint
== PIPE_VIDEO_ENTRYPOINT_BITSTREAM
) {
318 dec
->mpeg12_bs
= CALLOC_STRUCT(vl_mpg12_bs
);
321 vl_mpg12_bs_init(dec
->mpeg12_bs
, &dec
->base
);
322 dec
->base
.decode_bitstream
= nv84_decoder_decode_bitstream_mpeg12
;
328 ret
= nouveau_client_new(screen
->device
, &dec
->client
);
333 ret
= nouveau_object_new(&screen
->device
->object
, 0,
334 NOUVEAU_FIFO_CHANNEL_CLASS
,
335 &nv04_data
, sizeof(nv04_data
), &dec
->bsp_channel
);
339 ret
= nouveau_pushbuf_new(dec
->client
, dec
->bsp_channel
, 4,
340 32 * 1024, true, &dec
->bsp_pushbuf
);
344 ret
= nouveau_bufctx_new(dec
->client
, 1, &dec
->bsp_bufctx
);
349 ret
= nouveau_object_new(&screen
->device
->object
, 0,
350 NOUVEAU_FIFO_CHANNEL_CLASS
,
351 &nv04_data
, sizeof(nv04_data
), &dec
->vp_channel
);
354 ret
= nouveau_pushbuf_new(dec
->client
, dec
->vp_channel
, 4,
355 32 * 1024, true, &dec
->vp_pushbuf
);
359 ret
= nouveau_bufctx_new(dec
->client
, 1, &dec
->vp_bufctx
);
363 bsp_push
= dec
->bsp_pushbuf
;
364 vp_push
= dec
->vp_pushbuf
;
367 dec
->bsp_fw
= nv84_load_bsp_firmware(screen
->device
, dec
);
368 dec
->vp_fw
= nv84_load_vp_firmware(screen
->device
, dec
);
369 if (!dec
->bsp_fw
|| !dec
->vp_fw
)
373 dec
->vp_fw
= nv84_load_vp_firmware_mpeg(screen
->device
, dec
);
379 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_NOSNOOP
,
380 0, 0x40000, NULL
, &dec
->bsp_data
);
384 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_NOSNOOP
,
385 0, 0x40000, NULL
, &dec
->vp_data
);
389 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_NOSNOOP
,
391 2 * (dec
->vpring_deblock
+
392 dec
->vpring_residual
+
398 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_NOSNOOP
,
400 (templ
->max_references
+ 1) * dec
->frame_mbs
* 0x40 +
401 dec
->frame_size
+ 0x2000,
405 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_GART
,
406 0, 2 * (0x700 + MAX2(0x40000, 0x800 + 0x180 * dec
->frame_mbs
)),
407 NULL
, &dec
->bitstream
);
410 ret
= nouveau_bo_map(dec
->bitstream
, NOUVEAU_BO_WR
, dec
->client
);
413 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_GART
,
414 0, 0x2000, NULL
, &dec
->vp_params
);
417 ret
= nouveau_bo_map(dec
->vp_params
, NOUVEAU_BO_WR
, dec
->client
);
422 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_GART
,
424 align(0x20 * mb(templ
->width
) * mb(templ
->height
), 0x100) +
425 (6 * 64 * 8) * mb(templ
->width
) * mb(templ
->height
) + 0x100,
426 NULL
, &dec
->mpeg12_bo
);
429 ret
= nouveau_bo_map(dec
->mpeg12_bo
, NOUVEAU_BO_WR
, dec
->client
);
434 ret
= nouveau_bo_new(screen
->device
, NOUVEAU_BO_VRAM
,
435 0, 0x1000, NULL
, &dec
->fence
);
438 ret
= nouveau_bo_map(dec
->fence
, NOUVEAU_BO_WR
, dec
->client
);
441 *(uint32_t *)dec
->fence
->map
= 0;
444 nouveau_pushbuf_bufctx(bsp_push
, dec
->bsp_bufctx
);
445 nouveau_bufctx_refn(dec
->bsp_bufctx
, 0,
446 dec
->bsp_fw
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
447 nouveau_bufctx_refn(dec
->bsp_bufctx
, 0,
448 dec
->bsp_data
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
451 nouveau_pushbuf_bufctx(vp_push
, dec
->vp_bufctx
);
452 nouveau_bufctx_refn(dec
->vp_bufctx
, 0, dec
->vp_fw
,
453 NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
454 nouveau_bufctx_refn(dec
->vp_bufctx
, 0, dec
->vp_data
,
455 NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
458 ret
= nouveau_object_new(dec
->bsp_channel
, 0xbeef74b0, 0x74b0,
462 ret
= nouveau_object_new(dec
->vp_channel
, 0xbeef7476, 0x7476,
470 /* Zero out some parts of mbring/vpring. there's gotta be some cleaner way
471 * of doing this... perhaps makes sense to just copy the relevant logic
473 color
.f
[0] = color
.f
[1] = color
.f
[2] = color
.f
[3] = 0;
474 surf
.offset
= dec
->frame_size
;
476 surf
.height
= (templ
->max_references
+ 1) * dec
->frame_mbs
/ 4;
478 surf
.base
.format
= PIPE_FORMAT_B8G8R8A8_UNORM
;
479 surf
.base
.u
.tex
.level
= 0;
480 surf
.base
.texture
= &mip
.base
.base
;
481 mip
.level
[0].tile_mode
= 0;
482 mip
.level
[0].pitch
= surf
.width
* 4;
483 mip
.base
.domain
= NOUVEAU_BO_VRAM
;
484 mip
.base
.bo
= dec
->mbring
;
485 mip
.base
.address
= dec
->mbring
->offset
;
486 context
->clear_render_target(context
, &surf
.base
, &color
, 0, 0, 64, 4760);
487 surf
.offset
= dec
->vpring
->size
/ 2 - 0x1000;
490 mip
.level
[0].pitch
= surf
.width
* 4;
491 mip
.base
.bo
= dec
->vpring
;
492 mip
.base
.address
= dec
->vpring
->offset
;
493 context
->clear_render_target(context
, &surf
.base
, &color
, 0, 0, 1024, 1);
494 surf
.offset
= dec
->vpring
->size
- 0x1000;
495 context
->clear_render_target(context
, &surf
.base
, &color
, 0, 0, 1024, 1);
497 PUSH_SPACE(screen
->pushbuf
, 5);
498 PUSH_REFN(screen
->pushbuf
, dec
->fence
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
499 /* The clear_render_target is done via 3D engine, so use it to write to a
500 * sempahore to indicate that it's done.
502 BEGIN_NV04(screen
->pushbuf
, NV50_3D(QUERY_ADDRESS_HIGH
), 4);
503 PUSH_DATAh(screen
->pushbuf
, dec
->fence
->offset
);
504 PUSH_DATA (screen
->pushbuf
, dec
->fence
->offset
);
505 PUSH_DATA (screen
->pushbuf
, 1);
506 PUSH_DATA (screen
->pushbuf
, 0xf010);
507 PUSH_KICK (screen
->pushbuf
);
509 PUSH_SPACE(bsp_push
, 2 + 12 + 2 + 4 + 3);
511 BEGIN_NV04(bsp_push
, SUBC_BSP(NV01_SUBCHAN_OBJECT
), 1);
512 PUSH_DATA (bsp_push
, dec
->bsp
->handle
);
514 BEGIN_NV04(bsp_push
, SUBC_BSP(0x180), 11);
515 for (i
= 0; i
< 11; i
++)
516 PUSH_DATA(bsp_push
, nv04_data
.vram
);
517 BEGIN_NV04(bsp_push
, SUBC_BSP(0x1b8), 1);
518 PUSH_DATA (bsp_push
, nv04_data
.vram
);
520 BEGIN_NV04(bsp_push
, SUBC_BSP(0x600), 3);
521 PUSH_DATAh(bsp_push
, dec
->bsp_fw
->offset
);
522 PUSH_DATA (bsp_push
, dec
->bsp_fw
->offset
);
523 PUSH_DATA (bsp_push
, dec
->bsp_fw
->size
);
525 BEGIN_NV04(bsp_push
, SUBC_BSP(0x628), 2);
526 PUSH_DATA (bsp_push
, dec
->bsp_data
->offset
>> 8);
527 PUSH_DATA (bsp_push
, dec
->bsp_data
->size
);
528 PUSH_KICK (bsp_push
);
531 PUSH_SPACE(vp_push
, 2 + 12 + 2 + 4 + 3);
533 BEGIN_NV04(vp_push
, SUBC_VP(NV01_SUBCHAN_OBJECT
), 1);
534 PUSH_DATA (vp_push
, dec
->vp
->handle
);
536 BEGIN_NV04(vp_push
, SUBC_VP(0x180), 11);
537 for (i
= 0; i
< 11; i
++)
538 PUSH_DATA(vp_push
, nv04_data
.vram
);
540 BEGIN_NV04(vp_push
, SUBC_VP(0x1b8), 1);
541 PUSH_DATA (vp_push
, nv04_data
.vram
);
543 BEGIN_NV04(vp_push
, SUBC_VP(0x600), 3);
544 PUSH_DATAh(vp_push
, dec
->vp_fw
->offset
);
545 PUSH_DATA (vp_push
, dec
->vp_fw
->offset
);
546 PUSH_DATA (vp_push
, dec
->vp_fw
->size
);
548 BEGIN_NV04(vp_push
, SUBC_VP(0x628), 2);
549 PUSH_DATA (vp_push
, dec
->vp_data
->offset
>> 8);
550 PUSH_DATA (vp_push
, dec
->vp_data
->size
);
555 nv84_decoder_destroy(&dec
->base
);
559 static struct pipe_sampler_view
**
560 nv84_video_buffer_sampler_view_planes(struct pipe_video_buffer
*buffer
)
562 struct nv84_video_buffer
*buf
= (struct nv84_video_buffer
*)buffer
;
563 return buf
->sampler_view_planes
;
566 static struct pipe_sampler_view
**
567 nv84_video_buffer_sampler_view_components(struct pipe_video_buffer
*buffer
)
569 struct nv84_video_buffer
*buf
= (struct nv84_video_buffer
*)buffer
;
570 return buf
->sampler_view_components
;
573 static struct pipe_surface
**
574 nv84_video_buffer_surfaces(struct pipe_video_buffer
*buffer
)
576 struct nv84_video_buffer
*buf
= (struct nv84_video_buffer
*)buffer
;
577 return buf
->surfaces
;
581 nv84_video_buffer_destroy(struct pipe_video_buffer
*buffer
)
583 struct nv84_video_buffer
*buf
= (struct nv84_video_buffer
*)buffer
;
588 for (i
= 0; i
< VL_NUM_COMPONENTS
; ++i
) {
589 pipe_resource_reference(&buf
->resources
[i
], NULL
);
590 pipe_sampler_view_reference(&buf
->sampler_view_planes
[i
], NULL
);
591 pipe_sampler_view_reference(&buf
->sampler_view_components
[i
], NULL
);
592 pipe_surface_reference(&buf
->surfaces
[i
* 2], NULL
);
593 pipe_surface_reference(&buf
->surfaces
[i
* 2 + 1], NULL
);
596 nouveau_bo_ref(NULL
, &buf
->interlaced
);
597 nouveau_bo_ref(NULL
, &buf
->full
);
602 struct pipe_video_buffer
*
603 nv84_video_buffer_create(struct pipe_context
*pipe
,
604 const struct pipe_video_buffer
*template)
606 struct nv84_video_buffer
*buffer
;
607 struct pipe_resource templ
;
608 unsigned i
, j
, component
;
609 struct pipe_sampler_view sv_templ
;
610 struct pipe_surface surf_templ
;
611 struct nv50_miptree
*mt0
, *mt1
;
612 struct nouveau_screen
*screen
= &((struct nv50_context
*)pipe
)->screen
->base
;
613 union nouveau_bo_config cfg
;
616 if (getenv("XVMC_VL") || template->buffer_format
!= PIPE_FORMAT_NV12
)
617 return vl_video_buffer_create(pipe
, template);
619 if (!template->interlaced
) {
620 debug_printf("Require interlaced video buffers\n");
623 if (template->chroma_format
!= PIPE_VIDEO_CHROMA_FORMAT_420
) {
624 debug_printf("Must use 4:2:0 format\n");
629 * Note that there are always going to be exactly two planes, one for Y,
630 * and one for UV. These are also the resources. VP expects these to be
631 * adjacent, so they need to belong to the same BO.
634 buffer
= CALLOC_STRUCT(nv84_video_buffer
);
635 if (!buffer
) return NULL
;
639 buffer
->base
.buffer_format
= template->buffer_format
;
640 buffer
->base
.context
= pipe
;
641 buffer
->base
.destroy
= nv84_video_buffer_destroy
;
642 buffer
->base
.chroma_format
= template->chroma_format
;
643 buffer
->base
.width
= template->width
;
644 buffer
->base
.height
= template->height
;
645 buffer
->base
.get_sampler_view_planes
= nv84_video_buffer_sampler_view_planes
;
646 buffer
->base
.get_sampler_view_components
= nv84_video_buffer_sampler_view_components
;
647 buffer
->base
.get_surfaces
= nv84_video_buffer_surfaces
;
648 buffer
->base
.interlaced
= true;
650 memset(&templ
, 0, sizeof(templ
));
651 templ
.target
= PIPE_TEXTURE_2D_ARRAY
;
653 templ
.bind
= PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
;
654 templ
.format
= PIPE_FORMAT_R8_UNORM
;
655 templ
.width0
= align(template->width
, 2);
656 templ
.height0
= align(template->height
, 4) / 2;
657 templ
.flags
= NV50_RESOURCE_FLAG_VIDEO
| NV50_RESOURCE_FLAG_NOALLOC
;
658 templ
.array_size
= 2;
660 cfg
.nv50
.tile_mode
= 0x20;
661 cfg
.nv50
.memtype
= 0x70;
663 buffer
->resources
[0] = pipe
->screen
->resource_create(pipe
->screen
, &templ
);
664 if (!buffer
->resources
[0])
667 templ
.format
= PIPE_FORMAT_R8G8_UNORM
;
670 buffer
->resources
[1] = pipe
->screen
->resource_create(pipe
->screen
, &templ
);
671 if (!buffer
->resources
[1])
674 mt0
= nv50_miptree(buffer
->resources
[0]);
675 mt1
= nv50_miptree(buffer
->resources
[1]);
677 bo_size
= mt0
->total_size
+ mt1
->total_size
;
678 if (nouveau_bo_new(screen
->device
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_NOSNOOP
, 0,
679 bo_size
, &cfg
, &buffer
->interlaced
))
681 /* XXX Change reference frame management so that this is only allocated in
682 * the decoder when necessary. */
683 if (nouveau_bo_new(screen
->device
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_NOSNOOP
, 0,
684 bo_size
, &cfg
, &buffer
->full
))
687 nouveau_bo_ref(buffer
->interlaced
, &mt0
->base
.bo
);
688 mt0
->base
.domain
= NOUVEAU_BO_VRAM
;
689 mt0
->base
.address
= buffer
->interlaced
->offset
;
691 nouveau_bo_ref(buffer
->interlaced
, &mt1
->base
.bo
);
692 mt1
->base
.domain
= NOUVEAU_BO_VRAM
;
693 mt1
->base
.offset
= mt0
->total_size
;
694 mt1
->base
.address
= buffer
->interlaced
->offset
+ mt0
->total_size
;
696 memset(&sv_templ
, 0, sizeof(sv_templ
));
697 for (component
= 0, i
= 0; i
< 2; ++i
) {
698 struct pipe_resource
*res
= buffer
->resources
[i
];
699 unsigned nr_components
= util_format_get_nr_components(res
->format
);
701 u_sampler_view_default_template(&sv_templ
, res
, res
->format
);
702 buffer
->sampler_view_planes
[i
] =
703 pipe
->create_sampler_view(pipe
, res
, &sv_templ
);
704 if (!buffer
->sampler_view_planes
[i
])
707 for (j
= 0; j
< nr_components
; ++j
, ++component
) {
708 sv_templ
.swizzle_r
= sv_templ
.swizzle_g
= sv_templ
.swizzle_b
=
709 PIPE_SWIZZLE_RED
+ j
;
710 sv_templ
.swizzle_a
= PIPE_SWIZZLE_ONE
;
712 buffer
->sampler_view_components
[component
] =
713 pipe
->create_sampler_view(pipe
, res
, &sv_templ
);
714 if (!buffer
->sampler_view_components
[component
])
719 memset(&surf_templ
, 0, sizeof(surf_templ
));
720 for (j
= 0; j
< 2; ++j
) {
721 surf_templ
.format
= buffer
->resources
[j
]->format
;
722 surf_templ
.u
.tex
.first_layer
= surf_templ
.u
.tex
.last_layer
= 0;
723 buffer
->surfaces
[j
* 2] =
724 pipe
->create_surface(pipe
, buffer
->resources
[j
], &surf_templ
);
725 if (!buffer
->surfaces
[j
* 2])
728 surf_templ
.u
.tex
.first_layer
= surf_templ
.u
.tex
.last_layer
= 1;
729 buffer
->surfaces
[j
* 2 + 1] =
730 pipe
->create_surface(pipe
, buffer
->resources
[j
], &surf_templ
);
731 if (!buffer
->surfaces
[j
* 2 + 1])
735 return &buffer
->base
;
738 nv84_video_buffer_destroy(&buffer
->base
);
742 #define FIRMWARE_BSP_KERN 0x01
743 #define FIRMWARE_VP_KERN 0x02
744 #define FIRMWARE_BSP_H264 0x04
745 #define FIRMWARE_VP_MPEG2 0x08
746 #define FIRMWARE_VP_H264_1 0x10
747 #define FIRMWARE_VP_H264_2 0x20
748 #define FIRMWARE_PRESENT(val, fw) (val & FIRMWARE_ ## fw)
751 firmware_present(struct pipe_screen
*pscreen
, enum pipe_video_format codec
)
753 struct nouveau_screen
*screen
= nouveau_screen(pscreen
);
754 struct nouveau_object
*obj
= NULL
;
756 int checked
= screen
->firmware_info
.profiles_checked
;
759 if (!FIRMWARE_PRESENT(checked
, VP_KERN
)) {
760 nouveau_object_new(screen
->channel
, 0, 0x7476, NULL
, 0, &obj
);
762 screen
->firmware_info
.profiles_present
|= FIRMWARE_VP_KERN
;
763 nouveau_object_del(&obj
);
764 screen
->firmware_info
.profiles_checked
|= FIRMWARE_VP_KERN
;
767 if (codec
== PIPE_VIDEO_FORMAT_MPEG4_AVC
) {
768 if (!FIRMWARE_PRESENT(checked
, BSP_KERN
)) {
769 nouveau_object_new(screen
->channel
, 0, 0x74b0, NULL
, 0, &obj
);
771 screen
->firmware_info
.profiles_present
|= FIRMWARE_BSP_KERN
;
772 nouveau_object_del(&obj
);
773 screen
->firmware_info
.profiles_checked
|= FIRMWARE_BSP_KERN
;
776 if (!FIRMWARE_PRESENT(checked
, VP_H264_1
)) {
777 ret
= stat("/lib/firmware/nouveau/nv84_vp-h264-1", &s
);
778 if (!ret
&& s
.st_size
> 1000)
779 screen
->firmware_info
.profiles_present
|= FIRMWARE_VP_H264_1
;
780 screen
->firmware_info
.profiles_checked
|= FIRMWARE_VP_H264_1
;
783 /* should probably check the others, but assume that 1 means all */
785 present
= screen
->firmware_info
.profiles_present
;
786 return FIRMWARE_PRESENT(present
, VP_KERN
) &&
787 FIRMWARE_PRESENT(present
, BSP_KERN
) &&
788 FIRMWARE_PRESENT(present
, VP_H264_1
);
790 if (!FIRMWARE_PRESENT(checked
, VP_MPEG2
)) {
791 ret
= stat("/lib/firmware/nouveau/nv84_vp-mpeg12", &s
);
792 if (!ret
&& s
.st_size
> 1000)
793 screen
->firmware_info
.profiles_present
|= FIRMWARE_VP_MPEG2
;
794 screen
->firmware_info
.profiles_checked
|= FIRMWARE_VP_MPEG2
;
796 present
= screen
->firmware_info
.profiles_present
;
797 return FIRMWARE_PRESENT(present
, VP_KERN
) &&
798 FIRMWARE_PRESENT(present
, VP_MPEG2
);
803 nv84_screen_get_video_param(struct pipe_screen
*pscreen
,
804 enum pipe_video_profile profile
,
805 enum pipe_video_entrypoint entrypoint
,
806 enum pipe_video_cap param
)
808 enum pipe_video_format codec
;
811 case PIPE_VIDEO_CAP_SUPPORTED
:
812 codec
= u_reduce_video_profile(profile
);
813 return (codec
== PIPE_VIDEO_FORMAT_MPEG4_AVC
||
814 codec
== PIPE_VIDEO_FORMAT_MPEG12
) &&
815 firmware_present(pscreen
, codec
);
816 case PIPE_VIDEO_CAP_NPOT_TEXTURES
:
818 case PIPE_VIDEO_CAP_MAX_WIDTH
:
819 case PIPE_VIDEO_CAP_MAX_HEIGHT
:
821 case PIPE_VIDEO_CAP_PREFERED_FORMAT
:
822 return PIPE_FORMAT_NV12
;
823 case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED
:
824 case PIPE_VIDEO_CAP_PREFERS_INTERLACED
:
826 case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE
:
828 case PIPE_VIDEO_CAP_MAX_LEVEL
:
830 case PIPE_VIDEO_PROFILE_MPEG1
:
832 case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE
:
833 case PIPE_VIDEO_PROFILE_MPEG2_MAIN
:
835 case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE
:
836 case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN
:
837 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH
:
840 debug_printf("unknown video profile: %d\n", profile
);
844 debug_printf("unknown video param: %d\n", param
);
850 nv84_screen_video_supported(struct pipe_screen
*screen
,
851 enum pipe_format format
,
852 enum pipe_video_profile profile
,
853 enum pipe_video_entrypoint entrypoint
)
855 if (profile
!= PIPE_VIDEO_PROFILE_UNKNOWN
)
856 return format
== PIPE_FORMAT_NV12
;
858 return vl_video_buffer_is_format_supported(screen
, format
, profile
, entrypoint
);