Home | History | Annotate | Download | only in nv50
      1 /*
      2  * Copyright 2013 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 <sys/mman.h>
     24 #include <sys/stat.h>
     25 #include <sys/types.h>
     26 #include <fcntl.h>
     27 
     28 #include "util/u_format.h"
     29 #include "util/u_sampler.h"
     30 #include "vl/vl_zscan.h"
     31 
     32 #include "nv50/nv84_video.h"
     33 
     34 static int
     35 nv84_copy_firmware(const char *path, void *dest, ssize_t len)
     36 {
     37    int fd = open(path, O_RDONLY | O_CLOEXEC);
     38    ssize_t r;
     39    if (fd < 0) {
     40       fprintf(stderr, "opening firmware file %s failed: %m\n", path);
     41       return 1;
     42    }
     43    r = read(fd, dest, len);
     44    close(fd);
     45 
     46    if (r != len) {
     47       fprintf(stderr, "reading firwmare file %s failed: %m\n", path);
     48       return 1;
     49    }
     50 
     51    return 0;
     52 }
     53 
     54 static int
     55 filesize(const char *path)
     56 {
     57    int ret;
     58    struct stat statbuf;
     59 
     60    ret = stat(path, &statbuf);
     61    if (ret)
     62       return ret;
     63    return statbuf.st_size;
     64 }
     65 
     66 static struct nouveau_bo *
     67 nv84_load_firmwares(struct nouveau_device *dev, struct nv84_decoder *dec,
     68                     const char *fw1, const char *fw2)
     69 {
     70    int ret, size1, size2 = 0;
     71    struct nouveau_bo *fw;
     72 
     73    size1 = filesize(fw1);
     74    if (fw2)
     75       size2 = filesize(fw2);
     76    if (size1 < 0 || size2 < 0)
     77       return NULL;
     78 
     79    dec->vp_fw2_offset = align(size1, 0x100);
     80 
     81    ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, dec->vp_fw2_offset + size2, NULL, &fw);
     82    if (ret)
     83       return NULL;
     84    ret = nouveau_bo_map(fw, NOUVEAU_BO_WR, dec->client);
     85    if (ret)
     86       goto error;
     87 
     88    ret = nv84_copy_firmware(fw1, fw->map, size1);
     89    if (fw2 && !ret)
     90       ret = nv84_copy_firmware(fw2, fw->map + dec->vp_fw2_offset, size2);
     91    munmap(fw->map, fw->size);
     92    fw->map = NULL;
     93    if (!ret)
     94       return fw;
     95 error:
     96    nouveau_bo_ref(NULL, &fw);
     97    return NULL;
     98 }
     99 
    100 static struct nouveau_bo *
    101 nv84_load_bsp_firmware(struct nouveau_device *dev, struct nv84_decoder *dec)
    102 {
    103    return nv84_load_firmwares(
    104          dev, dec, "/lib/firmware/nouveau/nv84_bsp-h264", NULL);
    105 }
    106 
    107 static struct nouveau_bo *
    108 nv84_load_vp_firmware(struct nouveau_device *dev, struct nv84_decoder *dec)
    109 {
    110    return nv84_load_firmwares(
    111          dev, dec,
    112          "/lib/firmware/nouveau/nv84_vp-h264-1",
    113          "/lib/firmware/nouveau/nv84_vp-h264-2");
    114 }
    115 
    116 static struct nouveau_bo *
    117 nv84_load_vp_firmware_mpeg(struct nouveau_device *dev, struct nv84_decoder *dec)
    118 {
    119    return nv84_load_firmwares(
    120          dev, dec, "/lib/firmware/nouveau/nv84_vp-mpeg12", NULL);
    121 }
    122 
    123 static void
    124 nv84_decoder_decode_bitstream_h264(struct pipe_video_codec *decoder,
    125                                    struct pipe_video_buffer *video_target,
    126                                    struct pipe_picture_desc *picture,
    127                                    unsigned num_buffers,
    128                                    const void *const *data,
    129                                    const unsigned *num_bytes)
    130 {
    131    struct nv84_decoder *dec = (struct nv84_decoder *)decoder;
    132    struct nv84_video_buffer *target = (struct nv84_video_buffer *)video_target;
    133 
    134    struct pipe_h264_picture_desc *desc = (struct pipe_h264_picture_desc *)picture;
    135 
    136    assert(target->base.buffer_format == PIPE_FORMAT_NV12);
    137 
    138    nv84_decoder_bsp(dec, desc, num_buffers, data, num_bytes, target);
    139    nv84_decoder_vp_h264(dec, desc, target);
    140 }
    141 
    142 static void
    143 nv84_decoder_flush(struct pipe_video_codec *decoder)
    144 {
    145 }
    146 
    147 static void
    148 nv84_decoder_begin_frame_h264(struct pipe_video_codec *decoder,
    149                               struct pipe_video_buffer *target,
    150                               struct pipe_picture_desc *picture)
    151 {
    152 }
    153 
    154 static void
    155 nv84_decoder_end_frame_h264(struct pipe_video_codec *decoder,
    156                             struct pipe_video_buffer *target,
    157                             struct pipe_picture_desc *picture)
    158 {
    159 }
    160 
    161 static void
    162 nv84_decoder_decode_bitstream_mpeg12(struct pipe_video_codec *decoder,
    163                                      struct pipe_video_buffer *video_target,
    164                                      struct pipe_picture_desc *picture,
    165                                      unsigned num_buffers,
    166                                      const void *const *data,
    167                                      const unsigned *num_bytes)
    168 {
    169    struct nv84_decoder *dec = (struct nv84_decoder *)decoder;
    170 
    171    assert(video_target->buffer_format == PIPE_FORMAT_NV12);
    172 
    173    vl_mpg12_bs_decode(dec->mpeg12_bs,
    174                       video_target,
    175                       (struct pipe_mpeg12_picture_desc *)picture,
    176                       num_buffers,
    177                       data,
    178                       num_bytes);
    179 }
    180 
    181 static void
    182 nv84_decoder_begin_frame_mpeg12(struct pipe_video_codec *decoder,
    183                               struct pipe_video_buffer *target,
    184                               struct pipe_picture_desc *picture)
    185 {
    186    struct nv84_decoder *dec = (struct nv84_decoder *)decoder;
    187    struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture;
    188    int i;
    189 
    190    nouveau_bo_wait(dec->mpeg12_bo, NOUVEAU_BO_RDWR, dec->client);
    191    dec->mpeg12_mb_info = dec->mpeg12_bo->map + 0x100;
    192    dec->mpeg12_data = dec->mpeg12_bo->map + 0x100 +
    193       align(0x20 * mb(dec->base.width) * mb(dec->base.height), 0x100);
    194    if (desc->intra_matrix) {
    195       dec->zscan = desc->alternate_scan ? vl_zscan_alternate : vl_zscan_normal;
    196       for (i = 0; i < 64; i++) {
    197          dec->mpeg12_intra_matrix[i] = desc->intra_matrix[dec->zscan[i]];
    198          dec->mpeg12_non_intra_matrix[i] = desc->non_intra_matrix[dec->zscan[i]];
    199       }
    200       dec->mpeg12_intra_matrix[0] = 1 << (7 - desc->intra_dc_precision);
    201    }
    202 }
    203 
    204 static void
    205 nv84_decoder_end_frame_mpeg12(struct pipe_video_codec *decoder,
    206                               struct pipe_video_buffer *target,
    207                               struct pipe_picture_desc *picture)
    208 {
    209    nv84_decoder_vp_mpeg12(
    210          (struct nv84_decoder *)decoder,
    211          (struct pipe_mpeg12_picture_desc *)picture,
    212          (struct nv84_video_buffer *)target);
    213 }
    214 
    215 static void
    216 nv84_decoder_decode_macroblock(struct pipe_video_codec *decoder,
    217                                struct pipe_video_buffer *target,
    218                                struct pipe_picture_desc *picture,
    219                                const struct pipe_macroblock *macroblocks,
    220                                unsigned num_macroblocks)
    221 {
    222    const struct pipe_mpeg12_macroblock *mb = (const struct pipe_mpeg12_macroblock *)macroblocks;
    223    for (int i = 0; i < num_macroblocks; i++, mb++) {
    224       nv84_decoder_vp_mpeg12_mb(
    225             (struct nv84_decoder *)decoder,
    226             (struct pipe_mpeg12_picture_desc *)picture,
    227             mb);
    228    }
    229 }
    230 
    231 static void
    232 nv84_decoder_destroy(struct pipe_video_codec *decoder)
    233 {
    234    struct nv84_decoder *dec = (struct nv84_decoder *)decoder;
    235 
    236    nouveau_bo_ref(NULL, &dec->bsp_fw);
    237    nouveau_bo_ref(NULL, &dec->bsp_data);
    238    nouveau_bo_ref(NULL, &dec->vp_fw);
    239    nouveau_bo_ref(NULL, &dec->vp_data);
    240    nouveau_bo_ref(NULL, &dec->mbring);
    241    nouveau_bo_ref(NULL, &dec->vpring);
    242    nouveau_bo_ref(NULL, &dec->bitstream);
    243    nouveau_bo_ref(NULL, &dec->vp_params);
    244    nouveau_bo_ref(NULL, &dec->fence);
    245 
    246    nouveau_object_del(&dec->bsp);
    247    nouveau_object_del(&dec->vp);
    248 
    249    nouveau_bufctx_del(&dec->bsp_bufctx);
    250    nouveau_pushbuf_del(&dec->bsp_pushbuf);
    251    nouveau_object_del(&dec->bsp_channel);
    252 
    253    nouveau_bufctx_del(&dec->vp_bufctx);
    254    nouveau_pushbuf_del(&dec->vp_pushbuf);
    255    nouveau_object_del(&dec->vp_channel);
    256 
    257    nouveau_client_del(&dec->client);
    258 
    259    FREE(dec->mpeg12_bs);
    260    FREE(dec);
    261 }
    262 
    263 struct pipe_video_codec *
    264 nv84_create_decoder(struct pipe_context *context,
    265                     const struct pipe_video_codec *templ)
    266 {
    267    struct nv50_context *nv50 = (struct nv50_context *)context;
    268    struct nouveau_screen *screen = &nv50->screen->base;
    269    struct nv84_decoder *dec;
    270    struct nouveau_pushbuf *bsp_push, *vp_push;
    271    struct nv50_surface surf;
    272    struct nv50_miptree mip;
    273    union pipe_color_union color;
    274    struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 };
    275    int ret, i;
    276    int is_h264 = u_reduce_video_profile(templ->profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC;
    277    int is_mpeg12 = u_reduce_video_profile(templ->profile) == PIPE_VIDEO_FORMAT_MPEG12;
    278 
    279    if (getenv("XVMC_VL"))
    280       return vl_create_decoder(context, templ);
    281 
    282    if ((is_h264 && templ->entrypoint != PIPE_VIDEO_ENTRYPOINT_BITSTREAM) ||
    283        (is_mpeg12 && templ->entrypoint > PIPE_VIDEO_ENTRYPOINT_IDCT)) {
    284       debug_printf("%x\n", templ->entrypoint);
    285       return NULL;
    286    }
    287 
    288    if (!is_h264 && !is_mpeg12) {
    289       debug_printf("invalid profile: %x\n", templ->profile);
    290       return NULL;
    291    }
    292 
    293    dec = CALLOC_STRUCT(nv84_decoder);
    294    if (!dec)
    295       return NULL;
    296 
    297    dec->base = *templ;
    298    dec->base.context = context;
    299    dec->base.destroy = nv84_decoder_destroy;
    300    dec->base.flush = nv84_decoder_flush;
    301    if (is_h264) {
    302       dec->base.decode_bitstream = nv84_decoder_decode_bitstream_h264;
    303       dec->base.begin_frame = nv84_decoder_begin_frame_h264;
    304       dec->base.end_frame = nv84_decoder_end_frame_h264;
    305 
    306       dec->frame_mbs = mb(dec->base.width) * mb_half(dec->base.height) * 2;
    307       dec->frame_size = dec->frame_mbs << 8;
    308       dec->vpring_deblock = align(0x30 * dec->frame_mbs, 0x100);
    309       dec->vpring_residual = 0x2000 + MAX2(0x32000, 0x600 * dec->frame_mbs);
    310       dec->vpring_ctrl = MAX2(0x10000, align(0x1080 + 0x144 * dec->frame_mbs, 0x100));
    311    } else if (is_mpeg12) {
    312       dec->base.decode_macroblock = nv84_decoder_decode_macroblock;
    313       dec->base.begin_frame = nv84_decoder_begin_frame_mpeg12;
    314       dec->base.end_frame = nv84_decoder_end_frame_mpeg12;
    315 
    316       if (templ->entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) {
    317          dec->mpeg12_bs = CALLOC_STRUCT(vl_mpg12_bs);
    318          if (!dec->mpeg12_bs)
    319             goto fail;
    320          vl_mpg12_bs_init(dec->mpeg12_bs, &dec->base);
    321          dec->base.decode_bitstream = nv84_decoder_decode_bitstream_mpeg12;
    322       }
    323    } else {
    324       goto fail;
    325    }
    326 
    327    ret = nouveau_client_new(screen->device, &dec->client);
    328    if (ret)
    329       goto fail;
    330 
    331    if (is_h264) {
    332       ret = nouveau_object_new(&screen->device->object, 0,
    333                                NOUVEAU_FIFO_CHANNEL_CLASS,
    334                                &nv04_data, sizeof(nv04_data), &dec->bsp_channel);
    335       if (ret)
    336          goto fail;
    337 
    338       ret = nouveau_pushbuf_new(dec->client, dec->bsp_channel, 4,
    339                                 32 * 1024, true, &dec->bsp_pushbuf);
    340       if (ret)
    341          goto fail;
    342 
    343       ret = nouveau_bufctx_new(dec->client, 1, &dec->bsp_bufctx);
    344       if (ret)
    345          goto fail;
    346    }
    347 
    348    ret = nouveau_object_new(&screen->device->object, 0,
    349                             NOUVEAU_FIFO_CHANNEL_CLASS,
    350                             &nv04_data, sizeof(nv04_data), &dec->vp_channel);
    351    if (ret)
    352       goto fail;
    353    ret = nouveau_pushbuf_new(dec->client, dec->vp_channel, 4,
    354                              32 * 1024, true, &dec->vp_pushbuf);
    355    if (ret)
    356       goto fail;
    357 
    358    ret = nouveau_bufctx_new(dec->client, 1, &dec->vp_bufctx);
    359    if (ret)
    360       goto fail;
    361 
    362    bsp_push = dec->bsp_pushbuf;
    363    vp_push = dec->vp_pushbuf;
    364 
    365    if (is_h264) {
    366       dec->bsp_fw = nv84_load_bsp_firmware(screen->device, dec);
    367       dec->vp_fw = nv84_load_vp_firmware(screen->device, dec);
    368       if (!dec->bsp_fw || !dec->vp_fw)
    369          goto fail;
    370    }
    371    if (is_mpeg12) {
    372       dec->vp_fw = nv84_load_vp_firmware_mpeg(screen->device, dec);
    373       if (!dec->vp_fw)
    374          goto fail;
    375    }
    376 
    377    if (is_h264) {
    378       ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP,
    379                            0, 0x40000, NULL, &dec->bsp_data);
    380       if (ret)
    381          goto fail;
    382    }
    383    ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP,
    384                         0, 0x40000, NULL, &dec->vp_data);
    385    if (ret)
    386       goto fail;
    387    if (is_h264) {
    388       ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP,
    389                            0,
    390                            2 * (dec->vpring_deblock +
    391                                 dec->vpring_residual +
    392                                 dec->vpring_ctrl +
    393                                 0x1000),
    394                            NULL, &dec->vpring);
    395       if (ret)
    396          goto fail;
    397       ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP,
    398                            0,
    399                            (templ->max_references + 1) * dec->frame_mbs * 0x40 +
    400                            dec->frame_size + 0x2000,
    401                            NULL, &dec->mbring);
    402       if (ret)
    403          goto fail;
    404       ret = nouveau_bo_new(screen->device, NOUVEAU_BO_GART,
    405                            0, 2 * (0x700 + MAX2(0x40000, 0x800 + 0x180 * dec->frame_mbs)),
    406                            NULL, &dec->bitstream);
    407       if (ret)
    408          goto fail;
    409       ret = nouveau_bo_map(dec->bitstream, NOUVEAU_BO_WR, dec->client);
    410       if (ret)
    411          goto fail;
    412       ret = nouveau_bo_new(screen->device, NOUVEAU_BO_GART,
    413                            0, 0x2000, NULL, &dec->vp_params);
    414       if (ret)
    415          goto fail;
    416       ret = nouveau_bo_map(dec->vp_params, NOUVEAU_BO_WR, dec->client);
    417       if (ret)
    418          goto fail;
    419    }
    420    if (is_mpeg12) {
    421       ret = nouveau_bo_new(screen->device, NOUVEAU_BO_GART,
    422                            0,
    423                            align(0x20 * mb(templ->width) * mb(templ->height), 0x100) +
    424                            (6 * 64 * 8) * mb(templ->width) * mb(templ->height) + 0x100,
    425                            NULL, &dec->mpeg12_bo);
    426       if (ret)
    427          goto fail;
    428       ret = nouveau_bo_map(dec->mpeg12_bo, NOUVEAU_BO_WR, dec->client);
    429       if (ret)
    430          goto fail;
    431    }
    432 
    433    ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM,
    434                         0, 0x1000, NULL, &dec->fence);
    435    if (ret)
    436       goto fail;
    437    ret = nouveau_bo_map(dec->fence, NOUVEAU_BO_WR, dec->client);
    438    if (ret)
    439       goto fail;
    440    *(uint32_t *)dec->fence->map = 0;
    441 
    442    if (is_h264) {
    443       nouveau_pushbuf_bufctx(bsp_push, dec->bsp_bufctx);
    444       nouveau_bufctx_refn(dec->bsp_bufctx, 0,
    445                           dec->bsp_fw, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
    446       nouveau_bufctx_refn(dec->bsp_bufctx, 0,
    447                           dec->bsp_data, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
    448    }
    449 
    450    nouveau_pushbuf_bufctx(vp_push, dec->vp_bufctx);
    451    nouveau_bufctx_refn(dec->vp_bufctx, 0, dec->vp_fw,
    452                        NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
    453    nouveau_bufctx_refn(dec->vp_bufctx, 0, dec->vp_data,
    454                        NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
    455 
    456    if (is_h264 && !ret)
    457       ret = nouveau_object_new(dec->bsp_channel, 0xbeef74b0, 0x74b0,
    458                                NULL, 0, &dec->bsp);
    459 
    460    if (!ret)
    461       ret = nouveau_object_new(dec->vp_channel, 0xbeef7476, 0x7476,
    462                                NULL, 0, &dec->vp);
    463 
    464    if (ret)
    465       goto fail;
    466 
    467 
    468    if (is_h264) {
    469       /* Zero out some parts of mbring/vpring. there's gotta be some cleaner way
    470        * of doing this... perhaps makes sense to just copy the relevant logic
    471        * here. */
    472       color.f[0] = color.f[1] = color.f[2] = color.f[3] = 0;
    473       surf.offset = dec->frame_size;
    474       surf.width = 64;
    475       surf.height = (templ->max_references + 1) * dec->frame_mbs / 4;
    476       surf.depth = 1;
    477       surf.base.format = PIPE_FORMAT_B8G8R8A8_UNORM;
    478       surf.base.u.tex.level = 0;
    479       surf.base.texture = &mip.base.base;
    480       mip.level[0].tile_mode = 0;
    481       mip.level[0].pitch = surf.width * 4;
    482       mip.base.domain = NOUVEAU_BO_VRAM;
    483       mip.base.bo = dec->mbring;
    484       mip.base.address = dec->mbring->offset;
    485       context->clear_render_target(context, &surf.base, &color, 0, 0, 64, 4760, false);
    486       surf.offset = dec->vpring->size / 2 - 0x1000;
    487       surf.width = 1024;
    488       surf.height = 1;
    489       mip.level[0].pitch = surf.width * 4;
    490       mip.base.bo = dec->vpring;
    491       mip.base.address = dec->vpring->offset;
    492       context->clear_render_target(context, &surf.base, &color, 0, 0, 1024, 1, false);
    493       surf.offset = dec->vpring->size - 0x1000;
    494       context->clear_render_target(context, &surf.base, &color, 0, 0, 1024, 1, false);
    495 
    496       PUSH_SPACE(screen->pushbuf, 5);
    497       PUSH_REFN(screen->pushbuf, dec->fence, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
    498       /* The clear_render_target is done via 3D engine, so use it to write to a
    499        * sempahore to indicate that it's done.
    500        */
    501       BEGIN_NV04(screen->pushbuf, NV50_3D(QUERY_ADDRESS_HIGH), 4);
    502       PUSH_DATAh(screen->pushbuf, dec->fence->offset);
    503       PUSH_DATA (screen->pushbuf, dec->fence->offset);
    504       PUSH_DATA (screen->pushbuf, 1);
    505       PUSH_DATA (screen->pushbuf, 0xf010);
    506       PUSH_KICK (screen->pushbuf);
    507 
    508       PUSH_SPACE(bsp_push, 2 + 12 + 2 + 4 + 3);
    509 
    510       BEGIN_NV04(bsp_push, SUBC_BSP(NV01_SUBCHAN_OBJECT), 1);
    511       PUSH_DATA (bsp_push, dec->bsp->handle);
    512 
    513       BEGIN_NV04(bsp_push, SUBC_BSP(0x180), 11);
    514       for (i = 0; i < 11; i++)
    515          PUSH_DATA(bsp_push, nv04_data.vram);
    516       BEGIN_NV04(bsp_push, SUBC_BSP(0x1b8), 1);
    517       PUSH_DATA (bsp_push, nv04_data.vram);
    518 
    519       BEGIN_NV04(bsp_push, SUBC_BSP(0x600), 3);
    520       PUSH_DATAh(bsp_push, dec->bsp_fw->offset);
    521       PUSH_DATA (bsp_push, dec->bsp_fw->offset);
    522       PUSH_DATA (bsp_push, dec->bsp_fw->size);
    523 
    524       BEGIN_NV04(bsp_push, SUBC_BSP(0x628), 2);
    525       PUSH_DATA (bsp_push, dec->bsp_data->offset >> 8);
    526       PUSH_DATA (bsp_push, dec->bsp_data->size);
    527       PUSH_KICK (bsp_push);
    528    }
    529 
    530    PUSH_SPACE(vp_push, 2 + 12 + 2 + 4 + 3);
    531 
    532    BEGIN_NV04(vp_push, SUBC_VP(NV01_SUBCHAN_OBJECT), 1);
    533    PUSH_DATA (vp_push, dec->vp->handle);
    534 
    535    BEGIN_NV04(vp_push, SUBC_VP(0x180), 11);
    536    for (i = 0; i < 11; i++)
    537       PUSH_DATA(vp_push, nv04_data.vram);
    538 
    539    BEGIN_NV04(vp_push, SUBC_VP(0x1b8), 1);
    540    PUSH_DATA (vp_push, nv04_data.vram);
    541 
    542    BEGIN_NV04(vp_push, SUBC_VP(0x600), 3);
    543    PUSH_DATAh(vp_push, dec->vp_fw->offset);
    544    PUSH_DATA (vp_push, dec->vp_fw->offset);
    545    PUSH_DATA (vp_push, dec->vp_fw->size);
    546 
    547    BEGIN_NV04(vp_push, SUBC_VP(0x628), 2);
    548    PUSH_DATA (vp_push, dec->vp_data->offset >> 8);
    549    PUSH_DATA (vp_push, dec->vp_data->size);
    550    PUSH_KICK (vp_push);
    551 
    552    return &dec->base;
    553 fail:
    554    nv84_decoder_destroy(&dec->base);
    555    return NULL;
    556 }
    557 
    558 static struct pipe_sampler_view **
    559 nv84_video_buffer_sampler_view_planes(struct pipe_video_buffer *buffer)
    560 {
    561    struct nv84_video_buffer *buf = (struct nv84_video_buffer *)buffer;
    562    return buf->sampler_view_planes;
    563 }
    564 
    565 static struct pipe_sampler_view **
    566 nv84_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer)
    567 {
    568    struct nv84_video_buffer *buf = (struct nv84_video_buffer *)buffer;
    569    return buf->sampler_view_components;
    570 }
    571 
    572 static struct pipe_surface **
    573 nv84_video_buffer_surfaces(struct pipe_video_buffer *buffer)
    574 {
    575    struct nv84_video_buffer *buf = (struct nv84_video_buffer *)buffer;
    576    return buf->surfaces;
    577 }
    578 
    579 static void
    580 nv84_video_buffer_destroy(struct pipe_video_buffer *buffer)
    581 {
    582    struct nv84_video_buffer *buf = (struct nv84_video_buffer *)buffer;
    583    unsigned i;
    584 
    585    assert(buf);
    586 
    587    for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
    588       pipe_resource_reference(&buf->resources[i], NULL);
    589       pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL);
    590       pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL);
    591       pipe_surface_reference(&buf->surfaces[i * 2], NULL);
    592       pipe_surface_reference(&buf->surfaces[i * 2 + 1], NULL);
    593    }
    594 
    595    nouveau_bo_ref(NULL, &buf->interlaced);
    596    nouveau_bo_ref(NULL, &buf->full);
    597 
    598    FREE(buffer);
    599 }
    600 
    601 struct pipe_video_buffer *
    602 nv84_video_buffer_create(struct pipe_context *pipe,
    603                          const struct pipe_video_buffer *template)
    604 {
    605    struct nv84_video_buffer *buffer;
    606    struct pipe_resource templ;
    607    unsigned i, j, component;
    608    struct pipe_sampler_view sv_templ;
    609    struct pipe_surface surf_templ;
    610    struct nv50_miptree *mt0, *mt1;
    611    struct nouveau_screen *screen = &((struct nv50_context *)pipe)->screen->base;
    612    union nouveau_bo_config cfg;
    613    unsigned bo_size;
    614 
    615    if (getenv("XVMC_VL") || template->buffer_format != PIPE_FORMAT_NV12)
    616       return vl_video_buffer_create(pipe, template);
    617 
    618    if (!template->interlaced) {
    619       debug_printf("Require interlaced video buffers\n");
    620       return NULL;
    621    }
    622    if (template->chroma_format != PIPE_VIDEO_CHROMA_FORMAT_420) {
    623       debug_printf("Must use 4:2:0 format\n");
    624       return NULL;
    625    }
    626 
    627    /*
    628     * Note that there are always going to be exactly two planes, one for Y,
    629     * and one for UV. These are also the resources. VP expects these to be
    630     * adjacent, so they need to belong to the same BO.
    631     */
    632 
    633    buffer = CALLOC_STRUCT(nv84_video_buffer);
    634    if (!buffer) return NULL;
    635 
    636    buffer->mvidx = -1;
    637 
    638    buffer->base.buffer_format = template->buffer_format;
    639    buffer->base.context = pipe;
    640    buffer->base.destroy = nv84_video_buffer_destroy;
    641    buffer->base.chroma_format = template->chroma_format;
    642    buffer->base.width = template->width;
    643    buffer->base.height = template->height;
    644    buffer->base.get_sampler_view_planes = nv84_video_buffer_sampler_view_planes;
    645    buffer->base.get_sampler_view_components = nv84_video_buffer_sampler_view_components;
    646    buffer->base.get_surfaces = nv84_video_buffer_surfaces;
    647    buffer->base.interlaced = true;
    648 
    649    memset(&templ, 0, sizeof(templ));
    650    templ.target = PIPE_TEXTURE_2D_ARRAY;
    651    templ.depth0 = 1;
    652    templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
    653    templ.format = PIPE_FORMAT_R8_UNORM;
    654    templ.width0 = align(template->width, 2);
    655    templ.height0 = align(template->height, 4) / 2;
    656    templ.flags = NV50_RESOURCE_FLAG_VIDEO | NV50_RESOURCE_FLAG_NOALLOC;
    657    templ.array_size = 2;
    658 
    659    cfg.nv50.tile_mode = 0x20;
    660    cfg.nv50.memtype = 0x70;
    661 
    662    buffer->resources[0] = pipe->screen->resource_create(pipe->screen, &templ);
    663    if (!buffer->resources[0])
    664       goto error;
    665 
    666    templ.format = PIPE_FORMAT_R8G8_UNORM;
    667    templ.width0 /= 2;
    668    templ.height0 /= 2;
    669    buffer->resources[1] = pipe->screen->resource_create(pipe->screen, &templ);
    670    if (!buffer->resources[1])
    671       goto error;
    672 
    673    mt0 = nv50_miptree(buffer->resources[0]);
    674    mt1 = nv50_miptree(buffer->resources[1]);
    675 
    676    bo_size = mt0->total_size + mt1->total_size;
    677    if (nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP, 0,
    678                       bo_size, &cfg, &buffer->interlaced))
    679       goto error;
    680    /* XXX Change reference frame management so that this is only allocated in
    681     * the decoder when necessary. */
    682    if (nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP, 0,
    683                       bo_size, &cfg, &buffer->full))
    684       goto error;
    685 
    686    nouveau_bo_ref(buffer->interlaced, &mt0->base.bo);
    687    mt0->base.domain = NOUVEAU_BO_VRAM;
    688    mt0->base.address = buffer->interlaced->offset;
    689 
    690    nouveau_bo_ref(buffer->interlaced, &mt1->base.bo);
    691    mt1->base.domain = NOUVEAU_BO_VRAM;
    692    mt1->base.offset = mt0->total_size;
    693    mt1->base.address = buffer->interlaced->offset + mt0->total_size;
    694 
    695    memset(&sv_templ, 0, sizeof(sv_templ));
    696    for (component = 0, i = 0; i < 2; ++i ) {
    697       struct pipe_resource *res = buffer->resources[i];
    698       unsigned nr_components = util_format_get_nr_components(res->format);
    699 
    700       u_sampler_view_default_template(&sv_templ, res, res->format);
    701       buffer->sampler_view_planes[i] =
    702          pipe->create_sampler_view(pipe, res, &sv_templ);
    703       if (!buffer->sampler_view_planes[i])
    704          goto error;
    705 
    706       for (j = 0; j < nr_components; ++j, ++component) {
    707          sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b =
    708             PIPE_SWIZZLE_X + j;
    709          sv_templ.swizzle_a = PIPE_SWIZZLE_1;
    710 
    711          buffer->sampler_view_components[component] =
    712             pipe->create_sampler_view(pipe, res, &sv_templ);
    713          if (!buffer->sampler_view_components[component])
    714             goto error;
    715       }
    716    }
    717 
    718    memset(&surf_templ, 0, sizeof(surf_templ));
    719    for (j = 0; j < 2; ++j) {
    720       surf_templ.format = buffer->resources[j]->format;
    721       surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 0;
    722       buffer->surfaces[j * 2] =
    723          pipe->create_surface(pipe, buffer->resources[j], &surf_templ);
    724       if (!buffer->surfaces[j * 2])
    725          goto error;
    726 
    727       surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 1;
    728       buffer->surfaces[j * 2 + 1] =
    729          pipe->create_surface(pipe, buffer->resources[j], &surf_templ);
    730       if (!buffer->surfaces[j * 2 + 1])
    731          goto error;
    732    }
    733 
    734    return &buffer->base;
    735 
    736 error:
    737    nv84_video_buffer_destroy(&buffer->base);
    738    return NULL;
    739 }
    740 
    741 #define FIRMWARE_BSP_KERN  0x01
    742 #define FIRMWARE_VP_KERN   0x02
    743 #define FIRMWARE_BSP_H264  0x04
    744 #define FIRMWARE_VP_MPEG2  0x08
    745 #define FIRMWARE_VP_H264_1 0x10
    746 #define FIRMWARE_VP_H264_2 0x20
    747 #define FIRMWARE_PRESENT(val, fw) (val & FIRMWARE_ ## fw)
    748 
    749 static int
    750 firmware_present(struct pipe_screen *pscreen, enum pipe_video_format codec)
    751 {
    752    struct nouveau_screen *screen = nouveau_screen(pscreen);
    753    struct nouveau_object *obj = NULL;
    754    struct stat s;
    755    int checked = screen->firmware_info.profiles_checked;
    756    int present, ret;
    757 
    758    if (!FIRMWARE_PRESENT(checked, VP_KERN)) {
    759       ret = nouveau_object_new(screen->channel, 0, 0x7476, NULL, 0, &obj);
    760       if (!ret)
    761          screen->firmware_info.profiles_present |= FIRMWARE_VP_KERN;
    762       nouveau_object_del(&obj);
    763       screen->firmware_info.profiles_checked |= FIRMWARE_VP_KERN;
    764    }
    765 
    766    if (codec == PIPE_VIDEO_FORMAT_MPEG4_AVC) {
    767       if (!FIRMWARE_PRESENT(checked, BSP_KERN)) {
    768          ret = nouveau_object_new(screen->channel, 0, 0x74b0, NULL, 0, &obj);
    769          if (!ret)
    770             screen->firmware_info.profiles_present |= FIRMWARE_BSP_KERN;
    771          nouveau_object_del(&obj);
    772          screen->firmware_info.profiles_checked |= FIRMWARE_BSP_KERN;
    773       }
    774 
    775       if (!FIRMWARE_PRESENT(checked, VP_H264_1)) {
    776          ret = stat("/lib/firmware/nouveau/nv84_vp-h264-1", &s);
    777          if (!ret && s.st_size > 1000)
    778             screen->firmware_info.profiles_present |= FIRMWARE_VP_H264_1;
    779          screen->firmware_info.profiles_checked |= FIRMWARE_VP_H264_1;
    780       }
    781 
    782       /* should probably check the others, but assume that 1 means all */
    783 
    784       present = screen->firmware_info.profiles_present;
    785       return FIRMWARE_PRESENT(present, VP_KERN) &&
    786          FIRMWARE_PRESENT(present, BSP_KERN) &&
    787          FIRMWARE_PRESENT(present, VP_H264_1);
    788    } else {
    789       if (!FIRMWARE_PRESENT(checked, VP_MPEG2)) {
    790          ret = stat("/lib/firmware/nouveau/nv84_vp-mpeg12", &s);
    791          if (!ret && s.st_size > 1000)
    792             screen->firmware_info.profiles_present |= FIRMWARE_VP_MPEG2;
    793          screen->firmware_info.profiles_checked |= FIRMWARE_VP_MPEG2;
    794       }
    795       present = screen->firmware_info.profiles_present;
    796       return FIRMWARE_PRESENT(present, VP_KERN) &&
    797          FIRMWARE_PRESENT(present, VP_MPEG2);
    798    }
    799 }
    800 
    801 int
    802 nv84_screen_get_video_param(struct pipe_screen *pscreen,
    803                             enum pipe_video_profile profile,
    804                             enum pipe_video_entrypoint entrypoint,
    805                             enum pipe_video_cap param)
    806 {
    807    enum pipe_video_format codec;
    808 
    809    switch (param) {
    810    case PIPE_VIDEO_CAP_SUPPORTED:
    811       codec = u_reduce_video_profile(profile);
    812       return (codec == PIPE_VIDEO_FORMAT_MPEG4_AVC ||
    813               codec == PIPE_VIDEO_FORMAT_MPEG12) &&
    814          firmware_present(pscreen, codec);
    815    case PIPE_VIDEO_CAP_NPOT_TEXTURES:
    816       return 1;
    817    case PIPE_VIDEO_CAP_MAX_WIDTH:
    818    case PIPE_VIDEO_CAP_MAX_HEIGHT:
    819       return 2048;
    820    case PIPE_VIDEO_CAP_PREFERED_FORMAT:
    821       return PIPE_FORMAT_NV12;
    822    case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
    823    case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
    824       return true;
    825    case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
    826       return false;
    827    case PIPE_VIDEO_CAP_MAX_LEVEL:
    828       switch (profile) {
    829       case PIPE_VIDEO_PROFILE_MPEG1:
    830          return 0;
    831       case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
    832       case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
    833          return 3;
    834       case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
    835       case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
    836       case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
    837          return 41;
    838       default:
    839          debug_printf("unknown video profile: %d\n", profile);
    840          return 0;
    841       }
    842    default:
    843       debug_printf("unknown video param: %d\n", param);
    844       return 0;
    845    }
    846 }
    847 
    848 boolean
    849 nv84_screen_video_supported(struct pipe_screen *screen,
    850                             enum pipe_format format,
    851                             enum pipe_video_profile profile,
    852                             enum pipe_video_entrypoint entrypoint)
    853 {
    854    if (profile != PIPE_VIDEO_PROFILE_UNKNOWN)
    855       return format == PIPE_FORMAT_NV12;
    856 
    857    return vl_video_buffer_is_format_supported(screen, format, profile, entrypoint);
    858 }
    859