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/u_format.h" 36 #include "util/u_sampler.h" 37 38 static struct pipe_sampler_view ** 39 nouveau_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 45 static struct pipe_sampler_view ** 46 nouveau_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 52 static struct pipe_surface ** 53 nouveau_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 59 static void 60 nouveau_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 77 struct pipe_video_buffer * 78 nouveau_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(templat->chroma_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.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; 108 109 memset(&templ, 0, sizeof(templ)); 110 templ.target = PIPE_TEXTURE_2D_ARRAY; 111 templ.depth0 = 1; 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; 116 templ.flags = flags; 117 templ.array_size = 2; 118 119 buffer->resources[0] = pipe->screen->resource_create(pipe->screen, &templ); 120 if (!buffer->resources[0]) 121 goto error; 122 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]) 130 goto error; 131 } 132 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); 137 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]) 141 goto error; 142 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; 146 147 buffer->sampler_view_components[component] = pipe->create_sampler_view(pipe, res, &sv_templ); 148 if (!buffer->sampler_view_components[component]) 149 goto error; 150 } 151 } 152 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]) 159 goto error; 160 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]) 164 goto error; 165 } 166 167 return &buffer->base; 168 169 error: 170 nouveau_vp3_video_buffer_destroy(&buffer->base); 171 return NULL; 172 } 173 174 static void 175 nouveau_vp3_decoder_flush(struct pipe_video_codec *decoder) 176 { 177 } 178 179 static void 180 nouveau_vp3_decoder_begin_frame(struct pipe_video_codec *decoder, 181 struct pipe_video_buffer *target, 182 struct pipe_picture_desc *picture) 183 { 184 } 185 186 static void 187 nouveau_vp3_decoder_end_frame(struct pipe_video_codec *decoder, 188 struct pipe_video_buffer *target, 189 struct pipe_picture_desc *picture) 190 { 191 } 192 193 static void 194 nouveau_vp3_decoder_destroy(struct pipe_video_codec *decoder) 195 { 196 struct nouveau_vp3_decoder *dec = (struct nouveau_vp3_decoder *)decoder; 197 int i; 198 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); 205 #endif 206 nouveau_bo_ref(NULL, &dec->fw_bo); 207 208 for (i = 0; i < NOUVEAU_VP3_VIDEO_QDEPTH; ++i) 209 nouveau_bo_ref(NULL, &dec->bsp_bo[i]); 210 211 nouveau_object_del(&dec->bsp); 212 nouveau_object_del(&dec->vp); 213 nouveau_object_del(&dec->ppp); 214 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]); 219 } 220 } else { 221 nouveau_pushbuf_del(dec->pushbuf); 222 nouveau_object_del(dec->channel); 223 } 224 225 FREE(dec); 226 } 227 228 void 229 nouveau_vp3_decoder_init_common(struct pipe_video_codec *dec) 230 { 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; 235 } 236 237 static void vp3_getpath(enum pipe_video_profile profile, char *path) 238 { 239 switch (u_reduce_video_profile(profile)) { 240 case PIPE_VIDEO_FORMAT_MPEG12: { 241 sprintf(path, "/lib/firmware/nouveau/vuc-vp3-mpeg12-0"); 242 break; 243 } 244 case PIPE_VIDEO_FORMAT_VC1: { 245 sprintf(path, "/lib/firmware/nouveau/vuc-vp3-vc1-0"); 246 break; 247 } 248 case PIPE_VIDEO_FORMAT_MPEG4_AVC: { 249 sprintf(path, "/lib/firmware/nouveau/vuc-vp3-h264-0"); 250 break; 251 } 252 default: assert(0); 253 } 254 } 255 256 static void vp4_getpath(enum pipe_video_profile profile, char *path) 257 { 258 switch (u_reduce_video_profile(profile)) { 259 case PIPE_VIDEO_FORMAT_MPEG12: { 260 sprintf(path, "/lib/firmware/nouveau/vuc-mpeg12-0"); 261 break; 262 } 263 case PIPE_VIDEO_FORMAT_MPEG4: { 264 sprintf(path, "/lib/firmware/nouveau/vuc-mpeg4-0"); 265 break; 266 } 267 case PIPE_VIDEO_FORMAT_VC1: { 268 sprintf(path, "/lib/firmware/nouveau/vuc-vc1-0"); 269 break; 270 } 271 case PIPE_VIDEO_FORMAT_MPEG4_AVC: { 272 sprintf(path, "/lib/firmware/nouveau/vuc-h264-0"); 273 break; 274 } 275 default: assert(0); 276 } 277 } 278 279 int 280 nouveau_vp3_load_firmware(struct nouveau_vp3_decoder *dec, 281 enum pipe_video_profile profile, 282 unsigned chipset) 283 { 284 int fd; 285 char path[PATH_MAX]; 286 ssize_t r; 287 uint32_t *end, endval; 288 289 if (chipset >= 0xa3 && chipset != 0xaa && chipset != 0xac) 290 vp4_getpath(profile, path); 291 else 292 vp3_getpath(profile, path); 293 294 if (nouveau_bo_map(dec->fw_bo, NOUVEAU_BO_WR, dec->client)) 295 return 1; 296 297 fd = open(path, O_RDONLY | O_CLOEXEC); 298 if (fd < 0) { 299 fprintf(stderr, "opening firmware file %s failed: %m\n", path); 300 return 1; 301 } 302 r = read(fd, dec->fw_bo->map, 0x4000); 303 close(fd); 304 305 if (r < 0) { 306 fprintf(stderr, "reading firmware file %s failed: %m\n", path); 307 return 1; 308 } 309 310 if (r == 0x4000) { 311 fprintf(stderr, "firmware file %s too large!\n", path); 312 return 1; 313 } 314 315 if (r & 0xff) { 316 fprintf(stderr, "firmware file %s wrong size!\n", path); 317 return 1; 318 } 319 320 end = dec->fw_bo->map + r - 4; 321 endval = *end; 322 while (endval == *end) 323 end--; 324 325 r = (intptr_t)end - (intptr_t)dec->fw_bo->map + 4; 326 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); 331 break; 332 } 333 case PIPE_VIDEO_FORMAT_MPEG4: { 334 assert((r & 0xff) == 0xe0); 335 dec->fw_sizes = (0x2e0<<16) | (r - 0x2e0); 336 break; 337 } 338 case PIPE_VIDEO_FORMAT_VC1: { 339 assert((r & 0xff) == 0xac); 340 dec->fw_sizes = (0x3ac<<16) | (r - 0x3ac); 341 break; 342 } 343 case PIPE_VIDEO_FORMAT_MPEG4_AVC: { 344 assert((r & 0xff) == 0x70); 345 dec->fw_sizes = (0x370<<16) | (r - 0x370); 346 break; 347 } 348 default: 349 return 1; 350 } 351 munmap(dec->fw_bo->map, dec->fw_bo->size); 352 dec->fw_bo->map = NULL; 353 return 0; 354 } 355 356 static const struct nouveau_mclass 357 nouveau_decoder_msvld[] = { 358 { G98_MSVLD, -1 }, 359 { IGT21A_MSVLD, -1 }, 360 { GT212_MSVLD, -1 }, 361 { GF100_MSVLD, -1 }, 362 { GK104_MSVLD, -1 }, 363 {} 364 }; 365 366 static int 367 firmware_present(struct pipe_screen *pscreen, enum pipe_video_profile profile) 368 { 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; 373 int ret; 374 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}; 382 void *data = NULL; 383 int size; 384 385 if (chipset < 0xc0) { 386 data = &nv04_data; 387 size = sizeof(nv04_data); 388 } else if (chipset < 0xe0) { 389 data = &nvc0_args; 390 size = sizeof(nvc0_args); 391 } else { 392 data = &nve0_args; 393 size = sizeof(nve0_args); 394 } 395 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); 400 401 if (channel) { 402 ret = nouveau_object_mclass(channel, nouveau_decoder_msvld); 403 if (ret >= 0) 404 nouveau_object_new(channel, 0, nouveau_decoder_msvld[ret].oclass, 405 NULL, 0, &bsp); 406 if (bsp) 407 screen->firmware_info.profiles_present |= 1; 408 nouveau_object_del(&bsp); 409 nouveau_object_del(&channel); 410 } 411 screen->firmware_info.profiles_checked |= 1; 412 } 413 414 if (!(screen->firmware_info.profiles_present & 1)) 415 return 0; 416 417 /* For vp3/vp4 chipsets, make sure that the relevant firmware is present */ 418 if (!vp5 && !(screen->firmware_info.profiles_checked & (1 << profile))) { 419 char path[PATH_MAX]; 420 struct stat s; 421 if (vp3) 422 vp3_getpath(profile, path); 423 else 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); 429 } 430 431 return vp5 || (screen->firmware_info.profiles_present & (1 << profile)); 432 } 433 434 int 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) 439 { 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); 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 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: 461 return true; 462 case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE: 463 return false; 464 case PIPE_VIDEO_CAP_MAX_LEVEL: 465 switch (profile) { 466 case PIPE_VIDEO_PROFILE_MPEG1: 467 return 0; 468 case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE: 469 case PIPE_VIDEO_PROFILE_MPEG2_MAIN: 470 return 3; 471 case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE: 472 return 3; 473 case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE: 474 return 5; 475 case PIPE_VIDEO_PROFILE_VC1_SIMPLE: 476 return 1; 477 case PIPE_VIDEO_PROFILE_VC1_MAIN: 478 return 2; 479 case PIPE_VIDEO_PROFILE_VC1_ADVANCED: 480 return 4; 481 case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE: 482 case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN: 483 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH: 484 return 41; 485 default: 486 debug_printf("unknown video profile: %d\n", profile); 487 return 0; 488 } 489 default: 490 debug_printf("unknown video param: %d\n", param); 491 return 0; 492 } 493 } 494 495 boolean 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) 500 { 501 if (profile != PIPE_VIDEO_PROFILE_UNKNOWN) 502 return format == PIPE_FORMAT_NV12; 503 504 return vl_video_buffer_is_format_supported(screen, format, profile, entrypoint); 505 } 506