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