Home | History | Annotate | Download | only in nouveau
      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