Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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);
  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);
  493.       surf.offset = dec->vpring->size - 0x1000;
  494.       context->clear_render_target(context, &surf.base, &color, 0, 0, 1024, 1);
  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_RED + j;
  709.          sv_templ.swizzle_a = PIPE_SWIZZLE_ONE;
  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.       nouveau_object_new(screen->channel, 0, 0x7476, NULL, 0, &obj);
  760.       if (obj)
  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.          nouveau_object_new(screen->channel, 0, 0x74b0, NULL, 0, &obj);
  769.          if (obj)
  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.