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.
28 #include <nvif/class.h>
30 #include "nouveau_screen.h"
31 #include "nouveau_context.h"
32 #include "nouveau_vp3_video.h"
34 #include "util/u_video.h"
35 #include "util/u_format.h"
36 #include "util/u_sampler.h"
38 static struct pipe_sampler_view
**
39 nouveau_vp3_video_buffer_sampler_view_planes(struct pipe_video_buffer
*buffer
)
41 struct nouveau_vp3_video_buffer
*buf
= (struct nouveau_vp3_video_buffer
*)buffer
;
42 return buf
->sampler_view_planes
;
45 static struct pipe_sampler_view
**
46 nouveau_vp3_video_buffer_sampler_view_components(struct pipe_video_buffer
*buffer
)
48 struct nouveau_vp3_video_buffer
*buf
= (struct nouveau_vp3_video_buffer
*)buffer
;
49 return buf
->sampler_view_components
;
52 static struct pipe_surface
**
53 nouveau_vp3_video_buffer_surfaces(struct pipe_video_buffer
*buffer
)
55 struct nouveau_vp3_video_buffer
*buf
= (struct nouveau_vp3_video_buffer
*)buffer
;
60 nouveau_vp3_video_buffer_destroy(struct pipe_video_buffer
*buffer
)
62 struct nouveau_vp3_video_buffer
*buf
= (struct nouveau_vp3_video_buffer
*)buffer
;
67 for (i
= 0; i
< VL_NUM_COMPONENTS
; ++i
) {
68 pipe_resource_reference(&buf
->resources
[i
], NULL
);
69 pipe_sampler_view_reference(&buf
->sampler_view_planes
[i
], NULL
);
70 pipe_sampler_view_reference(&buf
->sampler_view_components
[i
], NULL
);
71 pipe_surface_reference(&buf
->surfaces
[i
* 2], NULL
);
72 pipe_surface_reference(&buf
->surfaces
[i
* 2 + 1], NULL
);
77 struct pipe_video_buffer
*
78 nouveau_vp3_video_buffer_create(struct pipe_context
*pipe
,
79 const struct pipe_video_buffer
*templat
,
82 struct nouveau_vp3_video_buffer
*buffer
;
83 struct pipe_resource templ
;
84 unsigned i
, j
, component
;
85 struct pipe_sampler_view sv_templ
;
86 struct pipe_surface surf_templ
;
88 if (getenv("XVMC_VL") || templat
->buffer_format
!= PIPE_FORMAT_NV12
)
89 return vl_video_buffer_create(pipe
, templat
);
91 assert(templat
->interlaced
);
92 assert(templat
->chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_420
);
94 buffer
= CALLOC_STRUCT(nouveau_vp3_video_buffer
);
98 buffer
->base
.buffer_format
= templat
->buffer_format
;
99 buffer
->base
.context
= pipe
;
100 buffer
->base
.destroy
= nouveau_vp3_video_buffer_destroy
;
101 buffer
->base
.chroma_format
= templat
->chroma_format
;
102 buffer
->base
.width
= templat
->width
;
103 buffer
->base
.height
= templat
->height
;
104 buffer
->base
.get_sampler_view_planes
= nouveau_vp3_video_buffer_sampler_view_planes
;
105 buffer
->base
.get_sampler_view_components
= nouveau_vp3_video_buffer_sampler_view_components
;
106 buffer
->base
.get_surfaces
= nouveau_vp3_video_buffer_surfaces
;
107 buffer
->base
.interlaced
= true;
109 memset(&templ
, 0, sizeof(templ
));
110 templ
.target
= PIPE_TEXTURE_2D_ARRAY
;
112 templ
.bind
= PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
;
113 templ
.format
= PIPE_FORMAT_R8_UNORM
;
114 templ
.width0
= buffer
->base
.width
;
115 templ
.height0
= (buffer
->base
.height
+ 1)/2;
117 templ
.array_size
= 2;
119 buffer
->resources
[0] = pipe
->screen
->resource_create(pipe
->screen
, &templ
);
120 if (!buffer
->resources
[0])
123 templ
.format
= PIPE_FORMAT_R8G8_UNORM
;
124 buffer
->num_planes
= 2;
125 templ
.width0
= (templ
.width0
+ 1) / 2;
126 templ
.height0
= (templ
.height0
+ 1) / 2;
127 for (i
= 1; i
< buffer
->num_planes
; ++i
) {
128 buffer
->resources
[i
] = pipe
->screen
->resource_create(pipe
->screen
, &templ
);
129 if (!buffer
->resources
[i
])
133 memset(&sv_templ
, 0, sizeof(sv_templ
));
134 for (component
= 0, i
= 0; i
< buffer
->num_planes
; ++i
) {
135 struct pipe_resource
*res
= buffer
->resources
[i
];
136 unsigned nr_components
= util_format_get_nr_components(res
->format
);
138 u_sampler_view_default_template(&sv_templ
, res
, res
->format
);
139 buffer
->sampler_view_planes
[i
] = pipe
->create_sampler_view(pipe
, res
, &sv_templ
);
140 if (!buffer
->sampler_view_planes
[i
])
143 for (j
= 0; j
< nr_components
; ++j
, ++component
) {
144 sv_templ
.swizzle_r
= sv_templ
.swizzle_g
= sv_templ
.swizzle_b
= PIPE_SWIZZLE_X
+ j
;
145 sv_templ
.swizzle_a
= PIPE_SWIZZLE_1
;
147 buffer
->sampler_view_components
[component
] = pipe
->create_sampler_view(pipe
, res
, &sv_templ
);
148 if (!buffer
->sampler_view_components
[component
])
153 memset(&surf_templ
, 0, sizeof(surf_templ
));
154 for (j
= 0; j
< buffer
->num_planes
; ++j
) {
155 surf_templ
.format
= buffer
->resources
[j
]->format
;
156 surf_templ
.u
.tex
.first_layer
= surf_templ
.u
.tex
.last_layer
= 0;
157 buffer
->surfaces
[j
* 2] = pipe
->create_surface(pipe
, buffer
->resources
[j
], &surf_templ
);
158 if (!buffer
->surfaces
[j
* 2])
161 surf_templ
.u
.tex
.first_layer
= surf_templ
.u
.tex
.last_layer
= 1;
162 buffer
->surfaces
[j
* 2 + 1] = pipe
->create_surface(pipe
, buffer
->resources
[j
], &surf_templ
);
163 if (!buffer
->surfaces
[j
* 2 + 1])
167 return &buffer
->base
;
170 nouveau_vp3_video_buffer_destroy(&buffer
->base
);
175 nouveau_vp3_decoder_flush(struct pipe_video_codec
*decoder
)
180 nouveau_vp3_decoder_begin_frame(struct pipe_video_codec
*decoder
,
181 struct pipe_video_buffer
*target
,
182 struct pipe_picture_desc
*picture
)
187 nouveau_vp3_decoder_end_frame(struct pipe_video_codec
*decoder
,
188 struct pipe_video_buffer
*target
,
189 struct pipe_picture_desc
*picture
)
194 nouveau_vp3_decoder_destroy(struct pipe_video_codec
*decoder
)
196 struct nouveau_vp3_decoder
*dec
= (struct nouveau_vp3_decoder
*)decoder
;
199 nouveau_bo_ref(NULL
, &dec
->ref_bo
);
200 nouveau_bo_ref(NULL
, &dec
->bitplane_bo
);
201 nouveau_bo_ref(NULL
, &dec
->inter_bo
[0]);
202 nouveau_bo_ref(NULL
, &dec
->inter_bo
[1]);
203 #if NOUVEAU_VP3_DEBUG_FENCE
204 nouveau_bo_ref(NULL
, &dec
->fence_bo
);
206 nouveau_bo_ref(NULL
, &dec
->fw_bo
);
208 for (i
= 0; i
< NOUVEAU_VP3_VIDEO_QDEPTH
; ++i
)
209 nouveau_bo_ref(NULL
, &dec
->bsp_bo
[i
]);
211 nouveau_object_del(&dec
->bsp
);
212 nouveau_object_del(&dec
->vp
);
213 nouveau_object_del(&dec
->ppp
);
215 if (dec
->channel
[0] != dec
->channel
[1]) {
216 for (i
= 0; i
< 3; ++i
) {
217 nouveau_pushbuf_del(&dec
->pushbuf
[i
]);
218 nouveau_object_del(&dec
->channel
[i
]);
221 nouveau_pushbuf_del(dec
->pushbuf
);
222 nouveau_object_del(dec
->channel
);
229 nouveau_vp3_decoder_init_common(struct pipe_video_codec
*dec
)
231 dec
->destroy
= nouveau_vp3_decoder_destroy
;
232 dec
->flush
= nouveau_vp3_decoder_flush
;
233 dec
->begin_frame
= nouveau_vp3_decoder_begin_frame
;
234 dec
->end_frame
= nouveau_vp3_decoder_end_frame
;
237 static void vp3_getpath(enum pipe_video_profile profile
, char *path
)
239 switch (u_reduce_video_profile(profile
)) {
240 case PIPE_VIDEO_FORMAT_MPEG12
: {
241 sprintf(path
, "/lib/firmware/nouveau/vuc-vp3-mpeg12-0");
244 case PIPE_VIDEO_FORMAT_VC1
: {
245 sprintf(path
, "/lib/firmware/nouveau/vuc-vp3-vc1-0");
248 case PIPE_VIDEO_FORMAT_MPEG4_AVC
: {
249 sprintf(path
, "/lib/firmware/nouveau/vuc-vp3-h264-0");
256 static void vp4_getpath(enum pipe_video_profile profile
, char *path
)
258 switch (u_reduce_video_profile(profile
)) {
259 case PIPE_VIDEO_FORMAT_MPEG12
: {
260 sprintf(path
, "/lib/firmware/nouveau/vuc-mpeg12-0");
263 case PIPE_VIDEO_FORMAT_MPEG4
: {
264 sprintf(path
, "/lib/firmware/nouveau/vuc-mpeg4-0");
267 case PIPE_VIDEO_FORMAT_VC1
: {
268 sprintf(path
, "/lib/firmware/nouveau/vuc-vc1-0");
271 case PIPE_VIDEO_FORMAT_MPEG4_AVC
: {
272 sprintf(path
, "/lib/firmware/nouveau/vuc-h264-0");
280 nouveau_vp3_load_firmware(struct nouveau_vp3_decoder
*dec
,
281 enum pipe_video_profile profile
,
287 uint32_t *end
, endval
;
289 if (chipset
>= 0xa3 && chipset
!= 0xaa && chipset
!= 0xac)
290 vp4_getpath(profile
, path
);
292 vp3_getpath(profile
, path
);
294 if (nouveau_bo_map(dec
->fw_bo
, NOUVEAU_BO_WR
, dec
->client
))
297 fd
= open(path
, O_RDONLY
| O_CLOEXEC
);
299 fprintf(stderr
, "opening firmware file %s failed: %m\n", path
);
302 r
= read(fd
, dec
->fw_bo
->map
, 0x4000);
306 fprintf(stderr
, "reading firmware file %s failed: %m\n", path
);
311 fprintf(stderr
, "firmware file %s too large!\n", path
);
316 fprintf(stderr
, "firmware file %s wrong size!\n", path
);
320 end
= dec
->fw_bo
->map
+ r
- 4;
322 while (endval
== *end
)
325 r
= (intptr_t)end
- (intptr_t)dec
->fw_bo
->map
+ 4;
327 switch (u_reduce_video_profile(profile
)) {
328 case PIPE_VIDEO_FORMAT_MPEG12
: {
329 assert((r
& 0xff) == 0xe0);
330 dec
->fw_sizes
= (0x2e0<<16) | (r
- 0x2e0);
333 case PIPE_VIDEO_FORMAT_MPEG4
: {
334 assert((r
& 0xff) == 0xe0);
335 dec
->fw_sizes
= (0x2e0<<16) | (r
- 0x2e0);
338 case PIPE_VIDEO_FORMAT_VC1
: {
339 assert((r
& 0xff) == 0xac);
340 dec
->fw_sizes
= (0x3ac<<16) | (r
- 0x3ac);
343 case PIPE_VIDEO_FORMAT_MPEG4_AVC
: {
344 assert((r
& 0xff) == 0x70);
345 dec
->fw_sizes
= (0x370<<16) | (r
- 0x370);
351 munmap(dec
->fw_bo
->map
, dec
->fw_bo
->size
);
352 dec
->fw_bo
->map
= NULL
;
356 static const struct nouveau_mclass
357 nouveau_decoder_msvld
[] = {
359 { IGT21A_MSVLD
, -1 },
367 firmware_present(struct pipe_screen
*pscreen
, enum pipe_video_profile profile
)
369 struct nouveau_screen
*screen
= nouveau_screen(pscreen
);
370 int chipset
= screen
->device
->chipset
;
371 int vp3
= chipset
< 0xa3 || chipset
== 0xaa || chipset
== 0xac;
372 int vp5
= chipset
>= 0xd0;
375 /* For all chipsets, try to create a BSP objects. Assume that if firmware
376 * is present for it, firmware is also present for VP/PPP */
377 if (!(screen
->firmware_info
.profiles_checked
& 1)) {
378 struct nouveau_object
*channel
= NULL
, *bsp
= NULL
;
379 struct nv04_fifo nv04_data
= {.vram
= 0xbeef0201, .gart
= 0xbeef0202};
380 struct nvc0_fifo nvc0_args
= {};
381 struct nve0_fifo nve0_args
= {.engine
= NVE0_FIFO_ENGINE_BSP
};
385 if (chipset
< 0xc0) {
387 size
= sizeof(nv04_data
);
388 } else if (chipset
< 0xe0) {
390 size
= sizeof(nvc0_args
);
393 size
= sizeof(nve0_args
);
396 /* kepler must have its own channel, so just do this for everyone */
397 nouveau_object_new(&screen
->device
->object
, 0,
398 NOUVEAU_FIFO_CHANNEL_CLASS
,
399 data
, size
, &channel
);
402 ret
= nouveau_object_mclass(channel
, nouveau_decoder_msvld
);
404 nouveau_object_new(channel
, 0, nouveau_decoder_msvld
[ret
].oclass
,
407 screen
->firmware_info
.profiles_present
|= 1;
408 nouveau_object_del(&bsp
);
409 nouveau_object_del(&channel
);
411 screen
->firmware_info
.profiles_checked
|= 1;
414 if (!(screen
->firmware_info
.profiles_present
& 1))
417 /* For vp3/vp4 chipsets, make sure that the relevant firmware is present */
418 if (!vp5
&& !(screen
->firmware_info
.profiles_checked
& (1 << profile
))) {
422 vp3_getpath(profile
, path
);
424 vp4_getpath(profile
, path
);
425 ret
= stat(path
, &s
);
426 if (!ret
&& s
.st_size
> 1000)
427 screen
->firmware_info
.profiles_present
|= (1 << profile
);
428 screen
->firmware_info
.profiles_checked
|= (1 << profile
);
431 return vp5
|| (screen
->firmware_info
.profiles_present
& (1 << profile
));
435 nouveau_vp3_screen_get_video_param(struct pipe_screen
*pscreen
,
436 enum pipe_video_profile profile
,
437 enum pipe_video_entrypoint entrypoint
,
438 enum pipe_video_cap param
)
440 int chipset
= nouveau_screen(pscreen
)->device
->chipset
;
441 int vp3
= chipset
< 0xa3 || chipset
== 0xaa || chipset
== 0xac;
442 int vp5
= chipset
>= 0xd0;
443 enum pipe_video_format codec
= u_reduce_video_profile(profile
);
445 case PIPE_VIDEO_CAP_SUPPORTED
:
446 /* VP3 does not support MPEG4, VP4+ do. */
447 return entrypoint
== PIPE_VIDEO_ENTRYPOINT_BITSTREAM
&&
448 profile
>= PIPE_VIDEO_PROFILE_MPEG1
&&
449 profile
< PIPE_VIDEO_PROFILE_HEVC_MAIN
&&
450 (!vp3
|| codec
!= PIPE_VIDEO_FORMAT_MPEG4
) &&
451 firmware_present(pscreen
, profile
);
452 case PIPE_VIDEO_CAP_NPOT_TEXTURES
:
454 case PIPE_VIDEO_CAP_MAX_WIDTH
:
455 case PIPE_VIDEO_CAP_MAX_HEIGHT
:
456 return vp5
? 4096 : 2048;
457 case PIPE_VIDEO_CAP_PREFERED_FORMAT
:
458 return PIPE_FORMAT_NV12
;
459 case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED
:
460 case PIPE_VIDEO_CAP_PREFERS_INTERLACED
:
462 case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE
:
464 case PIPE_VIDEO_CAP_MAX_LEVEL
:
466 case PIPE_VIDEO_PROFILE_MPEG1
:
468 case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE
:
469 case PIPE_VIDEO_PROFILE_MPEG2_MAIN
:
471 case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE
:
473 case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE
:
475 case PIPE_VIDEO_PROFILE_VC1_SIMPLE
:
477 case PIPE_VIDEO_PROFILE_VC1_MAIN
:
479 case PIPE_VIDEO_PROFILE_VC1_ADVANCED
:
481 case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE
:
482 case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN
:
483 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH
:
486 debug_printf("unknown video profile: %d\n", profile
);
490 debug_printf("unknown video param: %d\n", param
);
496 nouveau_vp3_screen_video_supported(struct pipe_screen
*screen
,
497 enum pipe_format format
,
498 enum pipe_video_profile profile
,
499 enum pipe_video_entrypoint entrypoint
)
501 if (profile
!= PIPE_VIDEO_PROFILE_UNKNOWN
)
502 return format
== PIPE_FORMAT_NV12
;
504 return vl_video_buffer_is_format_supported(screen
, format
, profile
, entrypoint
);