Home | History | Annotate | Download | only in nv50
      1 /*
      2  * Copyright 2011-2013 Maarten Lankhorst, Ilia Mirkin
      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 "nv50/nv98_video.h"
     24 
     25 #include "util/u_sampler.h"
     26 #include "util/u_format.h"
     27 
     28 #include <nvif/class.h>
     29 
     30 static void
     31 nv98_decoder_decode_bitstream(struct pipe_video_codec *decoder,
     32                               struct pipe_video_buffer *video_target,
     33                               struct pipe_picture_desc *picture,
     34                               unsigned num_buffers,
     35                               const void *const *data,
     36                               const unsigned *num_bytes)
     37 {
     38    struct nouveau_vp3_decoder *dec = (struct nouveau_vp3_decoder *)decoder;
     39    struct nouveau_vp3_video_buffer *target = (struct nouveau_vp3_video_buffer *)video_target;
     40    uint32_t comm_seq = ++dec->fence_seq;
     41    union pipe_desc desc;
     42 
     43    unsigned vp_caps, is_ref;
     44    MAYBE_UNUSED unsigned ret; /* used in debug checks */
     45    struct nouveau_vp3_video_buffer *refs[16] = {};
     46 
     47    desc.base = picture;
     48 
     49    assert(target->base.buffer_format == PIPE_FORMAT_NV12);
     50 
     51    ret = nv98_decoder_bsp(dec, desc, target, comm_seq,
     52                           num_buffers, data, num_bytes,
     53                           &vp_caps, &is_ref, refs);
     54 
     55    /* did we decode bitstream correctly? */
     56    assert(ret == 2);
     57 
     58    nv98_decoder_vp(dec, desc, target, comm_seq, vp_caps, is_ref, refs);
     59    nv98_decoder_ppp(dec, desc, target, comm_seq);
     60 }
     61 
     62 static const struct nouveau_mclass
     63 nv98_decoder_msvld[] = {
     64    { G98_MSVLD, -1 },
     65    { IGT21A_MSVLD, -1 },
     66    { GT212_MSVLD, -1 },
     67    {}
     68 };
     69 
     70 static const struct nouveau_mclass
     71 nv98_decoder_mspdec[] = {
     72    { G98_MSPDEC, -1 },
     73    { GT212_MSPDEC, -1 },
     74    {}
     75 };
     76 
     77 static const struct nouveau_mclass
     78 nv98_decoder_msppp[] = {
     79    { G98_MSPPP, -1 },
     80    { GT212_MSPPP, -1 },
     81    {}
     82 };
     83 
     84 struct pipe_video_codec *
     85 nv98_create_decoder(struct pipe_context *context,
     86                     const struct pipe_video_codec *templ)
     87 {
     88    struct nouveau_screen *screen = &((struct nv50_context *)context)->screen->base;
     89    struct nouveau_vp3_decoder *dec;
     90    struct nouveau_pushbuf **push;
     91    struct nv04_fifo nv04_data = {.vram = 0xbeef0201, .gart = 0xbeef0202};
     92 
     93    int ret, i;
     94    uint32_t codec = 1, ppp_codec = 3;
     95    uint32_t timeout;
     96    u32 tmp_size = 0;
     97 
     98    if (getenv("XVMC_VL"))
     99        return vl_create_decoder(context, templ);
    100 
    101    if (templ->entrypoint != PIPE_VIDEO_ENTRYPOINT_BITSTREAM) {
    102       debug_printf("%x\n", templ->entrypoint);
    103       return NULL;
    104    }
    105 
    106    dec = CALLOC_STRUCT(nouveau_vp3_decoder);
    107    if (!dec)
    108       return NULL;
    109    dec->client = screen->client;
    110    dec->base = *templ;
    111    nouveau_vp3_decoder_init_common(&dec->base);
    112 
    113    dec->bsp_idx = 5;
    114    dec->vp_idx = 6;
    115    dec->ppp_idx = 7;
    116 
    117    ret = nouveau_object_new(&screen->device->object, 0,
    118                             NOUVEAU_FIFO_CHANNEL_CLASS,
    119                             &nv04_data, sizeof(nv04_data), &dec->channel[0]);
    120 
    121    if (!ret)
    122       ret = nouveau_pushbuf_new(screen->client, dec->channel[0], 4,
    123                                 32 * 1024, true, &dec->pushbuf[0]);
    124 
    125    for (i = 1; i < 3; ++i) {
    126       dec->channel[i] = dec->channel[0];
    127       dec->pushbuf[i] = dec->pushbuf[0];
    128    }
    129    push = dec->pushbuf;
    130 
    131    if (!ret) {
    132       ret = nouveau_object_mclass(dec->channel[0], nv98_decoder_msvld);
    133       if (ret >= 0) {
    134          ret = nouveau_object_new(dec->channel[0], 0xbeef85b1,
    135                                   nv98_decoder_msvld[ret].oclass, NULL, 0,
    136                                   &dec->bsp);
    137       }
    138    }
    139 
    140    if (!ret) {
    141       ret = nouveau_object_mclass(dec->channel[1], nv98_decoder_mspdec);
    142       if (ret >= 0) {
    143          ret = nouveau_object_new(dec->channel[1], 0xbeef85b2,
    144                                   nv98_decoder_mspdec[ret].oclass, NULL, 0,
    145                                   &dec->vp);
    146       }
    147    }
    148 
    149    if (!ret) {
    150       ret = nouveau_object_mclass(dec->channel[2], nv98_decoder_msppp);
    151       if (ret >= 0) {
    152          ret = nouveau_object_new(dec->channel[2], 0xbeef85b3,
    153                                   nv98_decoder_msppp[ret].oclass, NULL, 0,
    154                                   &dec->ppp);
    155       }
    156    }
    157 
    158    if (ret)
    159       goto fail;
    160 
    161    BEGIN_NV04(push[0], SUBC_BSP(NV01_SUBCHAN_OBJECT), 1);
    162    PUSH_DATA (push[0], dec->bsp->handle);
    163 
    164    BEGIN_NV04(push[0], SUBC_BSP(0x180), 5);
    165    for (i = 0; i < 5; i++)
    166       PUSH_DATA (push[0], nv04_data.vram);
    167 
    168    BEGIN_NV04(push[1], SUBC_VP(NV01_SUBCHAN_OBJECT), 1);
    169    PUSH_DATA (push[1], dec->vp->handle);
    170 
    171    BEGIN_NV04(push[1], SUBC_VP(0x180), 6);
    172    for (i = 0; i < 6; i++)
    173       PUSH_DATA (push[1], nv04_data.vram);
    174 
    175    BEGIN_NV04(push[2], SUBC_PPP(NV01_SUBCHAN_OBJECT), 1);
    176    PUSH_DATA (push[2], dec->ppp->handle);
    177 
    178    BEGIN_NV04(push[2], SUBC_PPP(0x180), 5);
    179    for (i = 0; i < 5; i++)
    180       PUSH_DATA (push[2], nv04_data.vram);
    181 
    182    dec->base.context = context;
    183    dec->base.decode_bitstream = nv98_decoder_decode_bitstream;
    184 
    185    for (i = 0; i < NOUVEAU_VP3_VIDEO_QDEPTH && !ret; ++i)
    186       ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM,
    187                            0, 1 << 20, NULL, &dec->bsp_bo[i]);
    188    if (!ret)
    189       ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM,
    190                            0x100, 4 << 20, NULL, &dec->inter_bo[0]);
    191    if (!ret)
    192       nouveau_bo_ref(dec->inter_bo[0], &dec->inter_bo[1]);
    193    if (ret)
    194       goto fail;
    195 
    196    switch (u_reduce_video_profile(templ->profile)) {
    197    case PIPE_VIDEO_FORMAT_MPEG12: {
    198       codec = 1;
    199       assert(templ->max_references <= 2);
    200       break;
    201    }
    202    case PIPE_VIDEO_FORMAT_MPEG4: {
    203       codec = 4;
    204       tmp_size = mb(templ->height)*16 * mb(templ->width)*16;
    205       assert(templ->max_references <= 2);
    206       break;
    207    }
    208    case PIPE_VIDEO_FORMAT_VC1: {
    209       ppp_codec = codec = 2;
    210       tmp_size = mb(templ->height)*16 * mb(templ->width)*16;
    211       assert(templ->max_references <= 2);
    212       break;
    213    }
    214    case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
    215       codec = 3;
    216       dec->tmp_stride = 16 * mb_half(templ->width) * nouveau_vp3_video_align(templ->height) * 3 / 2;
    217       tmp_size = dec->tmp_stride * (templ->max_references + 1);
    218       assert(templ->max_references <= 16);
    219       break;
    220    }
    221    default:
    222       fprintf(stderr, "invalid codec\n");
    223       goto fail;
    224    }
    225 
    226    ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM, 0,
    227                            0x4000, NULL, &dec->fw_bo);
    228    if (ret)
    229       goto fail;
    230 
    231    ret = nouveau_vp3_load_firmware(dec, templ->profile, screen->device->chipset);
    232    if (ret)
    233       goto fw_fail;
    234 
    235    if (codec != 3) {
    236       ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM, 0,
    237                            0x400, NULL, &dec->bitplane_bo);
    238       if (ret)
    239          goto fail;
    240    }
    241 
    242    dec->ref_stride = mb(templ->width)*16 * (mb_half(templ->height)*32 + nouveau_vp3_video_align(templ->height)/2);
    243    ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM, 0,
    244                         dec->ref_stride * (templ->max_references+2) + tmp_size,
    245                         NULL, &dec->ref_bo);
    246    if (ret)
    247       goto fail;
    248 
    249    timeout = 0;
    250 
    251    BEGIN_NV04(push[0], SUBC_BSP(0x200), 2);
    252    PUSH_DATA (push[0], codec);
    253    PUSH_DATA (push[0], timeout);
    254 
    255    BEGIN_NV04(push[1], SUBC_VP(0x200), 2);
    256    PUSH_DATA (push[1], codec);
    257    PUSH_DATA (push[1], timeout);
    258 
    259    BEGIN_NV04(push[2], SUBC_PPP(0x200), 2);
    260    PUSH_DATA (push[2], ppp_codec);
    261    PUSH_DATA (push[2], timeout);
    262 
    263    ++dec->fence_seq;
    264 
    265 #if NOUVEAU_VP3_DEBUG_FENCE
    266    ret = nouveau_bo_new(screen->device, NOUVEAU_BO_GART|NOUVEAU_BO_MAP,
    267                         0, 0x1000, NULL, &dec->fence_bo);
    268    if (ret)
    269       goto fail;
    270 
    271    nouveau_bo_map(dec->fence_bo, NOUVEAU_BO_RDWR, screen->client);
    272    dec->fence_map = dec->fence_bo->map;
    273    dec->fence_map[0] = dec->fence_map[4] = dec->fence_map[8] = 0;
    274    dec->comm = (struct comm *)(dec->fence_map + (COMM_OFFSET/sizeof(*dec->fence_map)));
    275 
    276    /* So lets test if the fence is working? */
    277    nouveau_pushbuf_space(push[0], 16, 1, 0);
    278    PUSH_REFN (push[0], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
    279    BEGIN_NV04(push[0], SUBC_BSP(0x240), 3);
    280    PUSH_DATAh(push[0], dec->fence_bo->offset);
    281    PUSH_DATA (push[0], dec->fence_bo->offset);
    282    PUSH_DATA (push[0], dec->fence_seq);
    283 
    284    BEGIN_NV04(push[0], SUBC_BSP(0x304), 1);
    285    PUSH_DATA (push[0], 0);
    286    PUSH_KICK (push[0]);
    287 
    288    nouveau_pushbuf_space(push[1], 16, 1, 0);
    289    PUSH_REFN (push[1], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
    290    BEGIN_NV04(push[1], SUBC_VP(0x240), 3);
    291    PUSH_DATAh(push[1], (dec->fence_bo->offset + 0x10));
    292    PUSH_DATA (push[1], (dec->fence_bo->offset + 0x10));
    293    PUSH_DATA (push[1], dec->fence_seq);
    294 
    295    BEGIN_NV04(push[1], SUBC_VP(0x304), 1);
    296    PUSH_DATA (push[1], 0);
    297    PUSH_KICK (push[1]);
    298 
    299    nouveau_pushbuf_space(push[2], 16, 1, 0);
    300    PUSH_REFN (push[2], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
    301    BEGIN_NV04(push[2], SUBC_PPP(0x240), 3);
    302    PUSH_DATAh(push[2], (dec->fence_bo->offset + 0x20));
    303    PUSH_DATA (push[2], (dec->fence_bo->offset + 0x20));
    304    PUSH_DATA (push[2], dec->fence_seq);
    305 
    306    BEGIN_NV04(push[2], SUBC_PPP(0x304), 1);
    307    PUSH_DATA (push[2], 0);
    308    PUSH_KICK (push[2]);
    309 
    310    usleep(100);
    311    while (dec->fence_seq > dec->fence_map[0] ||
    312           dec->fence_seq > dec->fence_map[4] ||
    313           dec->fence_seq > dec->fence_map[8]) {
    314       debug_printf("%u: %u %u %u\n", dec->fence_seq, dec->fence_map[0], dec->fence_map[4], dec->fence_map[8]);
    315       usleep(100);
    316    }
    317    debug_printf("%u: %u %u %u\n", dec->fence_seq, dec->fence_map[0], dec->fence_map[4], dec->fence_map[8]);
    318 #endif
    319 
    320    return &dec->base;
    321 
    322 fw_fail:
    323    debug_printf("Cannot create decoder without firmware..\n");
    324    dec->base.destroy(&dec->base);
    325    return NULL;
    326 
    327 fail:
    328    debug_printf("Creation failed: %s (%i)\n", strerror(-ret), ret);
    329    dec->base.destroy(&dec->base);
    330    return NULL;
    331 }
    332 
    333 struct pipe_video_buffer *
    334 nv98_video_buffer_create(struct pipe_context *pipe,
    335                          const struct pipe_video_buffer *templat)
    336 {
    337    return nouveau_vp3_video_buffer_create(
    338          pipe, templat, NV50_RESOURCE_FLAG_VIDEO);
    339 }
    340