1 /*
2 * Copyright 2011-2013 Maarten Lankhorst
3 *
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:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
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.
21 */
22
23 #include <sys/mman.h>
24 #include <sys/stat.h>
25 #include <stdio.h>
26 #include <fcntl.h>
27
28 #include <nvif/class.h>
29
30 #include "nouveau_winsys.h"
31 #include "nouveau_screen.h"
32 #include "nouveau_context.h"
33 #include "nouveau_vp3_video.h"
34
35 #include "util/u_video.h"
36 #include "util/format/u_format.h"
37 #include "util/u_sampler.h"
38
39 static void
nouveau_vp3_video_buffer_resources(struct pipe_video_buffer * buffer,struct pipe_resource ** resources)40 nouveau_vp3_video_buffer_resources(struct pipe_video_buffer *buffer,
41 struct pipe_resource **resources)
42 {
43 struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
44 unsigned i;
45
46 assert(buf);
47
48 for (i = 0; i < buf->num_planes; ++i) {
49 resources[i] = buf->resources[i];
50 }
51 }
52
53 static struct pipe_sampler_view **
nouveau_vp3_video_buffer_sampler_view_planes(struct pipe_video_buffer * buffer)54 nouveau_vp3_video_buffer_sampler_view_planes(struct pipe_video_buffer *buffer)
55 {
56 struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
57 return buf->sampler_view_planes;
58 }
59
60 static struct pipe_sampler_view **
nouveau_vp3_video_buffer_sampler_view_components(struct pipe_video_buffer * buffer)61 nouveau_vp3_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer)
62 {
63 struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
64 return buf->sampler_view_components;
65 }
66
67 static struct pipe_surface **
nouveau_vp3_video_buffer_surfaces(struct pipe_video_buffer * buffer)68 nouveau_vp3_video_buffer_surfaces(struct pipe_video_buffer *buffer)
69 {
70 struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
71 return buf->surfaces;
72 }
73
74 static void
nouveau_vp3_video_buffer_destroy(struct pipe_video_buffer * buffer)75 nouveau_vp3_video_buffer_destroy(struct pipe_video_buffer *buffer)
76 {
77 struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
78 unsigned i;
79
80 assert(buf);
81
82 for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
83 pipe_resource_reference(&buf->resources[i], NULL);
84 pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL);
85 pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL);
86 pipe_surface_reference(&buf->surfaces[i * 2], NULL);
87 pipe_surface_reference(&buf->surfaces[i * 2 + 1], NULL);
88 }
89 FREE(buffer);
90 }
91
92 struct pipe_video_buffer *
nouveau_vp3_video_buffer_create(struct pipe_context * pipe,const struct pipe_video_buffer * templat,int flags)93 nouveau_vp3_video_buffer_create(struct pipe_context *pipe,
94 const struct pipe_video_buffer *templat,
95 int flags)
96 {
97 struct nouveau_vp3_video_buffer *buffer;
98 struct pipe_resource templ;
99 unsigned i, j, component;
100 struct pipe_sampler_view sv_templ;
101 struct pipe_surface surf_templ;
102
103 if (templat->buffer_format != PIPE_FORMAT_NV12)
104 return vl_video_buffer_create(pipe, templat);
105
106 assert(templat->interlaced);
107 assert(pipe_format_to_chroma_format(templat->buffer_format) == PIPE_VIDEO_CHROMA_FORMAT_420);
108
109 buffer = CALLOC_STRUCT(nouveau_vp3_video_buffer);
110 if (!buffer)
111 return NULL;
112
113 buffer->base.buffer_format = templat->buffer_format;
114 buffer->base.context = pipe;
115 buffer->base.destroy = nouveau_vp3_video_buffer_destroy;
116 buffer->base.width = templat->width;
117 buffer->base.height = templat->height;
118 buffer->base.get_resources = nouveau_vp3_video_buffer_resources;
119 buffer->base.get_sampler_view_planes = nouveau_vp3_video_buffer_sampler_view_planes;
120 buffer->base.get_sampler_view_components = nouveau_vp3_video_buffer_sampler_view_components;
121 buffer->base.get_surfaces = nouveau_vp3_video_buffer_surfaces;
122 buffer->base.interlaced = true;
123
124 memset(&templ, 0, sizeof(templ));
125 templ.target = PIPE_TEXTURE_2D_ARRAY;
126 templ.depth0 = 1;
127 templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
128 templ.format = PIPE_FORMAT_R8_UNORM;
129 templ.width0 = buffer->base.width;
130 templ.height0 = (buffer->base.height + 1)/2;
131 templ.flags = flags;
132 templ.array_size = 2;
133
134 buffer->resources[0] = pipe->screen->resource_create(pipe->screen, &templ);
135 if (!buffer->resources[0])
136 goto error;
137
138 templ.format = PIPE_FORMAT_R8G8_UNORM;
139 buffer->num_planes = 2;
140 templ.width0 = (templ.width0 + 1) / 2;
141 templ.height0 = (templ.height0 + 1) / 2;
142 for (i = 1; i < buffer->num_planes; ++i) {
143 buffer->resources[i] = pipe->screen->resource_create(pipe->screen, &templ);
144 if (!buffer->resources[i])
145 goto error;
146 }
147
148 memset(&sv_templ, 0, sizeof(sv_templ));
149 for (component = 0, i = 0; i < buffer->num_planes; ++i ) {
150 struct pipe_resource *res = buffer->resources[i];
151 unsigned nr_components = util_format_get_nr_components(res->format);
152
153 u_sampler_view_default_template(&sv_templ, res, res->format);
154 buffer->sampler_view_planes[i] = pipe->create_sampler_view(pipe, res, &sv_templ);
155 if (!buffer->sampler_view_planes[i])
156 goto error;
157
158 for (j = 0; j < nr_components; ++j, ++component) {
159 sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = PIPE_SWIZZLE_X + j;
160 sv_templ.swizzle_a = PIPE_SWIZZLE_1;
161
162 buffer->sampler_view_components[component] = pipe->create_sampler_view(pipe, res, &sv_templ);
163 if (!buffer->sampler_view_components[component])
164 goto error;
165 }
166 }
167
168 memset(&surf_templ, 0, sizeof(surf_templ));
169 for (j = 0; j < buffer->num_planes; ++j) {
170 surf_templ.format = buffer->resources[j]->format;
171 surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 0;
172 buffer->surfaces[j * 2] = pipe->create_surface(pipe, buffer->resources[j], &surf_templ);
173 if (!buffer->surfaces[j * 2])
174 goto error;
175
176 surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 1;
177 buffer->surfaces[j * 2 + 1] = pipe->create_surface(pipe, buffer->resources[j], &surf_templ);
178 if (!buffer->surfaces[j * 2 + 1])
179 goto error;
180 }
181
182 return &buffer->base;
183
184 error:
185 nouveau_vp3_video_buffer_destroy(&buffer->base);
186 return NULL;
187 }
188
189 static void
nouveau_vp3_decoder_flush(struct pipe_video_codec * decoder)190 nouveau_vp3_decoder_flush(struct pipe_video_codec *decoder)
191 {
192 }
193
194 static void
nouveau_vp3_decoder_begin_frame(struct pipe_video_codec * decoder,struct pipe_video_buffer * target,struct pipe_picture_desc * picture)195 nouveau_vp3_decoder_begin_frame(struct pipe_video_codec *decoder,
196 struct pipe_video_buffer *target,
197 struct pipe_picture_desc *picture)
198 {
199 }
200
201 static void
nouveau_vp3_decoder_end_frame(struct pipe_video_codec * decoder,struct pipe_video_buffer * target,struct pipe_picture_desc * picture)202 nouveau_vp3_decoder_end_frame(struct pipe_video_codec *decoder,
203 struct pipe_video_buffer *target,
204 struct pipe_picture_desc *picture)
205 {
206 }
207
208 static void
nouveau_vp3_decoder_destroy(struct pipe_video_codec * decoder)209 nouveau_vp3_decoder_destroy(struct pipe_video_codec *decoder)
210 {
211 struct nouveau_vp3_decoder *dec = (struct nouveau_vp3_decoder *)decoder;
212 int i;
213
214 nouveau_bo_ref(NULL, &dec->ref_bo);
215 nouveau_bo_ref(NULL, &dec->bitplane_bo);
216 nouveau_bo_ref(NULL, &dec->inter_bo[0]);
217 nouveau_bo_ref(NULL, &dec->inter_bo[1]);
218 #if NOUVEAU_VP3_DEBUG_FENCE
219 nouveau_bo_ref(NULL, &dec->fence_bo);
220 #endif
221 nouveau_bo_ref(NULL, &dec->fw_bo);
222
223 for (i = 0; i < NOUVEAU_VP3_VIDEO_QDEPTH; ++i)
224 nouveau_bo_ref(NULL, &dec->bsp_bo[i]);
225
226 nouveau_object_del(&dec->bsp);
227 nouveau_object_del(&dec->vp);
228 nouveau_object_del(&dec->ppp);
229
230 if (dec->channel[0] != dec->channel[1]) {
231 for (i = 0; i < 3; ++i) {
232 nouveau_pushbuf_destroy(&dec->pushbuf[i]);
233 nouveau_object_del(&dec->channel[i]);
234 }
235 } else {
236 nouveau_pushbuf_destroy(dec->pushbuf);
237 nouveau_object_del(dec->channel);
238 }
239
240 FREE(dec);
241 }
242
243 void
nouveau_vp3_decoder_init_common(struct pipe_video_codec * dec)244 nouveau_vp3_decoder_init_common(struct pipe_video_codec *dec)
245 {
246 dec->destroy = nouveau_vp3_decoder_destroy;
247 dec->flush = nouveau_vp3_decoder_flush;
248 dec->begin_frame = nouveau_vp3_decoder_begin_frame;
249 dec->end_frame = nouveau_vp3_decoder_end_frame;
250 }
251
vp3_getpath(enum pipe_video_profile profile,char * path)252 static void vp3_getpath(enum pipe_video_profile profile, char *path)
253 {
254 switch (u_reduce_video_profile(profile)) {
255 case PIPE_VIDEO_FORMAT_MPEG12: {
256 sprintf(path, "/lib/firmware/nouveau/vuc-vp3-mpeg12-0");
257 break;
258 }
259 case PIPE_VIDEO_FORMAT_VC1: {
260 sprintf(path, "/lib/firmware/nouveau/vuc-vp3-vc1-0");
261 break;
262 }
263 case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
264 sprintf(path, "/lib/firmware/nouveau/vuc-vp3-h264-0");
265 break;
266 }
267 default: assert(0);
268 }
269 }
270
vp4_getpath(enum pipe_video_profile profile,char * path)271 static void vp4_getpath(enum pipe_video_profile profile, char *path)
272 {
273 switch (u_reduce_video_profile(profile)) {
274 case PIPE_VIDEO_FORMAT_MPEG12: {
275 sprintf(path, "/lib/firmware/nouveau/vuc-mpeg12-0");
276 break;
277 }
278 case PIPE_VIDEO_FORMAT_MPEG4: {
279 sprintf(path, "/lib/firmware/nouveau/vuc-mpeg4-0");
280 break;
281 }
282 case PIPE_VIDEO_FORMAT_VC1: {
283 sprintf(path, "/lib/firmware/nouveau/vuc-vc1-0");
284 break;
285 }
286 case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
287 sprintf(path, "/lib/firmware/nouveau/vuc-h264-0");
288 break;
289 }
290 default: assert(0);
291 }
292 }
293
294 int
nouveau_vp3_load_firmware(struct nouveau_vp3_decoder * dec,enum pipe_video_profile profile,unsigned chipset)295 nouveau_vp3_load_firmware(struct nouveau_vp3_decoder *dec,
296 enum pipe_video_profile profile,
297 unsigned chipset)
298 {
299 int fd;
300 char path[PATH_MAX];
301 ssize_t r;
302 uint32_t *end, endval;
303 struct nouveau_screen *screen = nouveau_screen(dec->base.context->screen);
304
305 if (chipset >= 0xa3 && chipset != 0xaa && chipset != 0xac)
306 vp4_getpath(profile, path);
307 else
308 vp3_getpath(profile, path);
309
310 if (BO_MAP(screen, dec->fw_bo, NOUVEAU_BO_WR, dec->client))
311 return 1;
312
313 fd = open(path, O_RDONLY | O_CLOEXEC);
314 if (fd < 0) {
315 fprintf(stderr, "opening firmware file %s failed: %m\n", path);
316 return 1;
317 }
318 r = read(fd, dec->fw_bo->map, 0x4000);
319 close(fd);
320
321 if (r < 0) {
322 fprintf(stderr, "reading firmware file %s failed: %m\n", path);
323 return 1;
324 }
325
326 if (r == 0x4000) {
327 fprintf(stderr, "firmware file %s too large!\n", path);
328 return 1;
329 }
330
331 if (r & 0xff) {
332 fprintf(stderr, "firmware file %s wrong size!\n", path);
333 return 1;
334 }
335
336 end = dec->fw_bo->map + r - 4;
337 endval = *end;
338 while (endval == *end)
339 end--;
340
341 r = (intptr_t)end - (intptr_t)dec->fw_bo->map + 4;
342
343 switch (u_reduce_video_profile(profile)) {
344 case PIPE_VIDEO_FORMAT_MPEG12: {
345 assert((r & 0xff) == 0xe0);
346 dec->fw_sizes = (0x2e0<<16) | (r - 0x2e0);
347 break;
348 }
349 case PIPE_VIDEO_FORMAT_MPEG4: {
350 assert((r & 0xff) == 0xe0);
351 dec->fw_sizes = (0x2e0<<16) | (r - 0x2e0);
352 break;
353 }
354 case PIPE_VIDEO_FORMAT_VC1: {
355 assert((r & 0xff) == 0xac);
356 dec->fw_sizes = (0x3ac<<16) | (r - 0x3ac);
357 break;
358 }
359 case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
360 assert((r & 0xff) == 0x70);
361 dec->fw_sizes = (0x370<<16) | (r - 0x370);
362 break;
363 }
364 default:
365 return 1;
366 }
367 munmap(dec->fw_bo->map, dec->fw_bo->size);
368 dec->fw_bo->map = NULL;
369 return 0;
370 }
371
372 static const struct nouveau_mclass
373 nouveau_decoder_msvld[] = {
374 { G98_MSVLD, -1 },
375 { IGT21A_MSVLD, -1 },
376 { GT212_MSVLD, -1 },
377 { GF100_MSVLD, -1 },
378 { GK104_MSVLD, -1 },
379 {}
380 };
381
382 static int
firmware_present(struct pipe_screen * pscreen,enum pipe_video_profile profile)383 firmware_present(struct pipe_screen *pscreen, enum pipe_video_profile profile)
384 {
385 struct nouveau_screen *screen = nouveau_screen(pscreen);
386 int chipset = screen->device->chipset;
387 int vp3 = chipset < 0xa3 || chipset == 0xaa || chipset == 0xac;
388 int vp5 = chipset >= 0xd0;
389 int ret;
390
391 /* For all chipsets, try to create a BSP objects. Assume that if firmware
392 * is present for it, firmware is also present for VP/PPP */
393 if (!(screen->firmware_info.profiles_checked & 1)) {
394 struct nouveau_object *channel = NULL, *bsp = NULL;
395 struct nv04_fifo nv04_data = {.vram = 0xbeef0201, .gart = 0xbeef0202};
396 struct nvc0_fifo nvc0_args = {};
397 struct nve0_fifo nve0_args = {.engine = NVE0_FIFO_ENGINE_BSP};
398 void *data = NULL;
399 int size;
400
401 if (chipset < 0xc0) {
402 data = &nv04_data;
403 size = sizeof(nv04_data);
404 } else if (chipset < 0xe0) {
405 data = &nvc0_args;
406 size = sizeof(nvc0_args);
407 } else {
408 data = &nve0_args;
409 size = sizeof(nve0_args);
410 }
411
412 /* kepler must have its own channel, so just do this for everyone */
413 nouveau_object_new(&screen->device->object, 0,
414 NOUVEAU_FIFO_CHANNEL_CLASS,
415 data, size, &channel);
416
417 if (channel) {
418 ret = nouveau_object_mclass(channel, nouveau_decoder_msvld);
419 if (ret >= 0)
420 nouveau_object_new(channel, 0, nouveau_decoder_msvld[ret].oclass,
421 NULL, 0, &bsp);
422 if (bsp)
423 screen->firmware_info.profiles_present |= 1;
424 nouveau_object_del(&bsp);
425 nouveau_object_del(&channel);
426 }
427 screen->firmware_info.profiles_checked |= 1;
428 }
429
430 if (!(screen->firmware_info.profiles_present & 1))
431 return 0;
432
433 /* For vp3/vp4 chipsets, make sure that the relevant firmware is present */
434 if (!vp5 && !(screen->firmware_info.profiles_checked & (1 << profile))) {
435 char path[PATH_MAX];
436 struct stat s;
437 if (vp3)
438 vp3_getpath(profile, path);
439 else
440 vp4_getpath(profile, path);
441 ret = stat(path, &s);
442 if (!ret && s.st_size > 1000)
443 screen->firmware_info.profiles_present |= (1 << profile);
444 screen->firmware_info.profiles_checked |= (1 << profile);
445 }
446
447 return vp5 || (screen->firmware_info.profiles_present & (1 << profile));
448 }
449
450 int
nouveau_vp3_screen_get_video_param(struct pipe_screen * pscreen,enum pipe_video_profile profile,enum pipe_video_entrypoint entrypoint,enum pipe_video_cap param)451 nouveau_vp3_screen_get_video_param(struct pipe_screen *pscreen,
452 enum pipe_video_profile profile,
453 enum pipe_video_entrypoint entrypoint,
454 enum pipe_video_cap param)
455 {
456 const int chipset = nouveau_screen(pscreen)->device->chipset;
457 /* Feature Set B = vp3, C = vp4, D = vp5 */
458 const bool vp3 = chipset < 0xa3 || chipset == 0xaa || chipset == 0xac;
459 const bool vp5 = chipset >= 0xd0;
460 enum pipe_video_format codec = u_reduce_video_profile(profile);
461 switch (param) {
462 case PIPE_VIDEO_CAP_SUPPORTED:
463 /* VP3 does not support MPEG4, VP4+ do. */
464 return entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM &&
465 profile >= PIPE_VIDEO_PROFILE_MPEG1 &&
466 profile < PIPE_VIDEO_PROFILE_HEVC_MAIN &&
467 (!vp3 || codec != PIPE_VIDEO_FORMAT_MPEG4) &&
468 firmware_present(pscreen, profile);
469 case PIPE_VIDEO_CAP_NPOT_TEXTURES:
470 return 1;
471 case PIPE_VIDEO_CAP_MAX_WIDTH:
472 switch (codec) {
473 case PIPE_VIDEO_FORMAT_MPEG12:
474 return vp5 ? 4032 : 2048;
475 case PIPE_VIDEO_FORMAT_MPEG4:
476 return 2048;
477 case PIPE_VIDEO_FORMAT_VC1:
478 return 2048;
479 case PIPE_VIDEO_FORMAT_MPEG4_AVC:
480 if (vp3)
481 return 2032;
482 if (vp5)
483 return 4032;
484 return 2048; /* vp4 */
485 case PIPE_VIDEO_FORMAT_UNKNOWN:
486 return vp5 ? 4032 : 2048;
487 default:
488 debug_printf("unknown video codec: %d\n", codec);
489 return 0;
490 }
491 case PIPE_VIDEO_CAP_MAX_HEIGHT:
492 switch (codec) {
493 case PIPE_VIDEO_FORMAT_MPEG12:
494 return vp5 ? 4048 : 2048;
495 case PIPE_VIDEO_FORMAT_MPEG4:
496 return 2048;
497 case PIPE_VIDEO_FORMAT_VC1:
498 return 2048;
499 case PIPE_VIDEO_FORMAT_MPEG4_AVC:
500 if (vp3)
501 return 2048;
502 if (vp5)
503 return 4080;
504 return 2048; /* vp4 */
505 case PIPE_VIDEO_FORMAT_UNKNOWN:
506 return vp5 ? 4080 : 2048;
507 default:
508 debug_printf("unknown video codec: %d\n", codec);
509 return 0;
510 }
511 case PIPE_VIDEO_CAP_PREFERED_FORMAT:
512 return PIPE_FORMAT_NV12;
513 case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
514 case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
515 return true;
516 case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
517 return false;
518 case PIPE_VIDEO_CAP_MAX_LEVEL:
519 switch (profile) {
520 case PIPE_VIDEO_PROFILE_MPEG1:
521 return 0;
522 case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
523 case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
524 return 3;
525 case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE:
526 return 3;
527 case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE:
528 return 5;
529 case PIPE_VIDEO_PROFILE_VC1_SIMPLE:
530 return 1;
531 case PIPE_VIDEO_PROFILE_VC1_MAIN:
532 return 2;
533 case PIPE_VIDEO_PROFILE_VC1_ADVANCED:
534 return 4;
535 case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
536 case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE:
537 case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
538 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
539 return 41;
540 default:
541 debug_printf("unknown video profile: %d\n", profile);
542 return 0;
543 }
544 case PIPE_VIDEO_CAP_MAX_MACROBLOCKS:
545 switch (codec) {
546 case PIPE_VIDEO_FORMAT_MPEG12:
547 return vp5 ? 65536 : 8192;
548 case PIPE_VIDEO_FORMAT_MPEG4:
549 return 8192;
550 case PIPE_VIDEO_FORMAT_VC1:
551 return 8190;
552 case PIPE_VIDEO_FORMAT_MPEG4_AVC:
553 if (vp3)
554 return 8190;
555 if (vp5)
556 return 65536;
557 return 8192; /* vp4 */
558 default:
559 debug_printf("unknown video codec: %d\n", codec);
560 return 0;
561 }
562 default:
563 debug_printf("unknown video param: %d\n", param);
564 return 0;
565 }
566 }
567
568 bool
nouveau_vp3_screen_video_supported(struct pipe_screen * screen,enum pipe_format format,enum pipe_video_profile profile,enum pipe_video_entrypoint entrypoint)569 nouveau_vp3_screen_video_supported(struct pipe_screen *screen,
570 enum pipe_format format,
571 enum pipe_video_profile profile,
572 enum pipe_video_entrypoint entrypoint)
573 {
574 if (profile != PIPE_VIDEO_PROFILE_UNKNOWN)
575 return format == PIPE_FORMAT_NV12;
576
577 return vl_video_buffer_is_format_supported(screen, format, profile, entrypoint);
578 }
579