Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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 "nouveau_screen.h"
  29. #include "nouveau_context.h"
  30. #include "nouveau_vp3_video.h"
  31.  
  32. #include "util/u_video.h"
  33. #include "util/u_format.h"
  34. #include "util/u_sampler.h"
  35.  
  36. static struct pipe_sampler_view **
  37. nouveau_vp3_video_buffer_sampler_view_planes(struct pipe_video_buffer *buffer)
  38. {
  39.    struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
  40.    return buf->sampler_view_planes;
  41. }
  42.  
  43. static struct pipe_sampler_view **
  44. nouveau_vp3_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer)
  45. {
  46.    struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
  47.    return buf->sampler_view_components;
  48. }
  49.  
  50. static struct pipe_surface **
  51. nouveau_vp3_video_buffer_surfaces(struct pipe_video_buffer *buffer)
  52. {
  53.    struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
  54.    return buf->surfaces;
  55. }
  56.  
  57. static void
  58. nouveau_vp3_video_buffer_destroy(struct pipe_video_buffer *buffer)
  59. {
  60.    struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
  61.    unsigned i;
  62.  
  63.    assert(buf);
  64.  
  65.    for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
  66.       pipe_resource_reference(&buf->resources[i], NULL);
  67.       pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL);
  68.       pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL);
  69.       pipe_surface_reference(&buf->surfaces[i * 2], NULL);
  70.       pipe_surface_reference(&buf->surfaces[i * 2 + 1], NULL);
  71.    }
  72.    FREE(buffer);
  73. }
  74.  
  75. struct pipe_video_buffer *
  76. nouveau_vp3_video_buffer_create(struct pipe_context *pipe,
  77.                          const struct pipe_video_buffer *templat,
  78.                          int flags)
  79. {
  80.    struct nouveau_vp3_video_buffer *buffer;
  81.    struct pipe_resource templ;
  82.    unsigned i, j, component;
  83.    struct pipe_sampler_view sv_templ;
  84.    struct pipe_surface surf_templ;
  85.  
  86.    assert(templat->interlaced);
  87.    if (getenv("XVMC_VL") || templat->buffer_format != PIPE_FORMAT_NV12)
  88.       return vl_video_buffer_create(pipe, templat);
  89.  
  90.    assert(templat->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
  91.  
  92.    buffer = CALLOC_STRUCT(nouveau_vp3_video_buffer);
  93.    if (!buffer)
  94.       return NULL;
  95.  
  96.    buffer->base.buffer_format = templat->buffer_format;
  97.    buffer->base.context = pipe;
  98.    buffer->base.destroy = nouveau_vp3_video_buffer_destroy;
  99.    buffer->base.chroma_format = templat->chroma_format;
  100.    buffer->base.width = templat->width;
  101.    buffer->base.height = templat->height;
  102.    buffer->base.get_sampler_view_planes = nouveau_vp3_video_buffer_sampler_view_planes;
  103.    buffer->base.get_sampler_view_components = nouveau_vp3_video_buffer_sampler_view_components;
  104.    buffer->base.get_surfaces = nouveau_vp3_video_buffer_surfaces;
  105.    buffer->base.interlaced = true;
  106.  
  107.    memset(&templ, 0, sizeof(templ));
  108.    templ.target = PIPE_TEXTURE_2D_ARRAY;
  109.    templ.depth0 = 1;
  110.    templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
  111.    templ.format = PIPE_FORMAT_R8_UNORM;
  112.    templ.width0 = buffer->base.width;
  113.    templ.height0 = (buffer->base.height + 1)/2;
  114.    templ.flags = flags;
  115.    templ.array_size = 2;
  116.  
  117.    buffer->resources[0] = pipe->screen->resource_create(pipe->screen, &templ);
  118.    if (!buffer->resources[0])
  119.       goto error;
  120.  
  121.    templ.format = PIPE_FORMAT_R8G8_UNORM;
  122.    buffer->num_planes = 2;
  123.    templ.width0 = (templ.width0 + 1) / 2;
  124.    templ.height0 = (templ.height0 + 1) / 2;
  125.    for (i = 1; i < buffer->num_planes; ++i) {
  126.       buffer->resources[i] = pipe->screen->resource_create(pipe->screen, &templ);
  127.       if (!buffer->resources[i])
  128.          goto error;
  129.    }
  130.  
  131.    memset(&sv_templ, 0, sizeof(sv_templ));
  132.    for (component = 0, i = 0; i < buffer->num_planes; ++i ) {
  133.       struct pipe_resource *res = buffer->resources[i];
  134.       unsigned nr_components = util_format_get_nr_components(res->format);
  135.  
  136.       u_sampler_view_default_template(&sv_templ, res, res->format);
  137.       buffer->sampler_view_planes[i] = pipe->create_sampler_view(pipe, res, &sv_templ);
  138.       if (!buffer->sampler_view_planes[i])
  139.          goto error;
  140.  
  141.       for (j = 0; j < nr_components; ++j, ++component) {
  142.          sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = PIPE_SWIZZLE_RED + j;
  143.          sv_templ.swizzle_a = PIPE_SWIZZLE_ONE;
  144.  
  145.          buffer->sampler_view_components[component] = pipe->create_sampler_view(pipe, res, &sv_templ);
  146.          if (!buffer->sampler_view_components[component])
  147.             goto error;
  148.       }
  149.   }
  150.  
  151.    memset(&surf_templ, 0, sizeof(surf_templ));
  152.    for (j = 0; j < buffer->num_planes; ++j) {
  153.       surf_templ.format = buffer->resources[j]->format;
  154.       surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 0;
  155.       buffer->surfaces[j * 2] = pipe->create_surface(pipe, buffer->resources[j], &surf_templ);
  156.       if (!buffer->surfaces[j * 2])
  157.          goto error;
  158.  
  159.       surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 1;
  160.       buffer->surfaces[j * 2 + 1] = pipe->create_surface(pipe, buffer->resources[j], &surf_templ);
  161.       if (!buffer->surfaces[j * 2 + 1])
  162.          goto error;
  163.    }
  164.  
  165.    return &buffer->base;
  166.  
  167. error:
  168.    nouveau_vp3_video_buffer_destroy(&buffer->base);
  169.    return NULL;
  170. }
  171.  
  172. static void
  173. nouveau_vp3_decoder_flush(struct pipe_video_codec *decoder)
  174. {
  175. }
  176.  
  177. static void
  178. nouveau_vp3_decoder_begin_frame(struct pipe_video_codec *decoder,
  179.                                 struct pipe_video_buffer *target,
  180.                                 struct pipe_picture_desc *picture)
  181. {
  182. }
  183.  
  184. static void
  185. nouveau_vp3_decoder_end_frame(struct pipe_video_codec *decoder,
  186.                               struct pipe_video_buffer *target,
  187.                               struct pipe_picture_desc *picture)
  188. {
  189. }
  190.  
  191. static void
  192. nouveau_vp3_decoder_destroy(struct pipe_video_codec *decoder)
  193. {
  194.    struct nouveau_vp3_decoder *dec = (struct nouveau_vp3_decoder *)decoder;
  195.    int i;
  196.  
  197.    nouveau_bo_ref(NULL, &dec->ref_bo);
  198.    nouveau_bo_ref(NULL, &dec->bitplane_bo);
  199.    nouveau_bo_ref(NULL, &dec->inter_bo[0]);
  200.    nouveau_bo_ref(NULL, &dec->inter_bo[1]);
  201. #if NOUVEAU_VP3_DEBUG_FENCE
  202.    nouveau_bo_ref(NULL, &dec->fence_bo);
  203. #endif
  204.    nouveau_bo_ref(NULL, &dec->fw_bo);
  205.  
  206.    for (i = 0; i < NOUVEAU_VP3_VIDEO_QDEPTH; ++i)
  207.       nouveau_bo_ref(NULL, &dec->bsp_bo[i]);
  208.  
  209.    nouveau_object_del(&dec->bsp);
  210.    nouveau_object_del(&dec->vp);
  211.    nouveau_object_del(&dec->ppp);
  212.  
  213.    if (dec->channel[0] != dec->channel[1]) {
  214.       for (i = 0; i < 3; ++i) {
  215.          nouveau_pushbuf_del(&dec->pushbuf[i]);
  216.          nouveau_object_del(&dec->channel[i]);
  217.       }
  218.    } else {
  219.       nouveau_pushbuf_del(dec->pushbuf);
  220.       nouveau_object_del(dec->channel);
  221.    }
  222.  
  223.    FREE(dec);
  224. }
  225.  
  226. void
  227. nouveau_vp3_decoder_init_common(struct pipe_video_codec *dec)
  228. {
  229.    dec->destroy = nouveau_vp3_decoder_destroy;
  230.    dec->flush = nouveau_vp3_decoder_flush;
  231.    dec->begin_frame = nouveau_vp3_decoder_begin_frame;
  232.    dec->end_frame = nouveau_vp3_decoder_end_frame;
  233. }
  234.  
  235. static void vp3_getpath(enum pipe_video_profile profile, char *path)
  236. {
  237.    switch (u_reduce_video_profile(profile)) {
  238.       case PIPE_VIDEO_FORMAT_MPEG12: {
  239.          sprintf(path, "/lib/firmware/nouveau/vuc-vp3-mpeg12-0");
  240.          break;
  241.       }
  242.       case PIPE_VIDEO_FORMAT_VC1: {
  243.          sprintf(path, "/lib/firmware/nouveau/vuc-vp3-vc1-0");
  244.          break;
  245.       }
  246.       case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
  247.          sprintf(path, "/lib/firmware/nouveau/vuc-vp3-h264-0");
  248.          break;
  249.       }
  250.       default: assert(0);
  251.    }
  252. }
  253.  
  254. static void vp4_getpath(enum pipe_video_profile profile, char *path)
  255. {
  256.    switch (u_reduce_video_profile(profile)) {
  257.       case PIPE_VIDEO_FORMAT_MPEG12: {
  258.          sprintf(path, "/lib/firmware/nouveau/vuc-mpeg12-0");
  259.          break;
  260.       }
  261.       case PIPE_VIDEO_FORMAT_MPEG4: {
  262.          sprintf(path, "/lib/firmware/nouveau/vuc-mpeg4-0");
  263.          break;
  264.       }
  265.       case PIPE_VIDEO_FORMAT_VC1: {
  266.          sprintf(path, "/lib/firmware/nouveau/vuc-vc1-0");
  267.          break;
  268.       }
  269.       case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
  270.          sprintf(path, "/lib/firmware/nouveau/vuc-h264-0");
  271.          break;
  272.       }
  273.       default: assert(0);
  274.    }
  275. }
  276.  
  277. int
  278. nouveau_vp3_load_firmware(struct nouveau_vp3_decoder *dec,
  279.                           enum pipe_video_profile profile,
  280.                           unsigned chipset)
  281. {
  282.    int fd;
  283.    char path[PATH_MAX];
  284.    ssize_t r;
  285.    uint32_t *end, endval;
  286.  
  287.    if (chipset >= 0xa3 && chipset != 0xaa && chipset != 0xac)
  288.       vp4_getpath(profile, path);
  289.    else
  290.       vp3_getpath(profile, path);
  291.  
  292.    if (nouveau_bo_map(dec->fw_bo, NOUVEAU_BO_WR, dec->client))
  293.       return 1;
  294.  
  295.    fd = open(path, O_RDONLY | O_CLOEXEC);
  296.    if (fd < 0) {
  297.       fprintf(stderr, "opening firmware file %s failed: %m\n", path);
  298.       return 1;
  299.    }
  300.    r = read(fd, dec->fw_bo->map, 0x4000);
  301.    close(fd);
  302.  
  303.    if (r < 0) {
  304.       fprintf(stderr, "reading firmware file %s failed: %m\n", path);
  305.       return 1;
  306.    }
  307.  
  308.    if (r == 0x4000) {
  309.       fprintf(stderr, "firmware file %s too large!\n", path);
  310.       return 1;
  311.    }
  312.  
  313.    if (r & 0xff) {
  314.       fprintf(stderr, "firmware file %s wrong size!\n", path);
  315.       return 1;
  316.    }
  317.  
  318.    end = dec->fw_bo->map + r - 4;
  319.    endval = *end;
  320.    while (endval == *end)
  321.       end--;
  322.  
  323.    r = (intptr_t)end - (intptr_t)dec->fw_bo->map + 4;
  324.  
  325.    switch (u_reduce_video_profile(profile)) {
  326.       case PIPE_VIDEO_FORMAT_MPEG12: {
  327.          assert((r & 0xff) == 0xe0);
  328.          dec->fw_sizes = (0x2e0<<16) | (r - 0x2e0);
  329.          break;
  330.       }
  331.       case PIPE_VIDEO_FORMAT_MPEG4: {
  332.          assert((r & 0xff) == 0xe0);
  333.          dec->fw_sizes = (0x2e0<<16) | (r - 0x2e0);
  334.          break;
  335.       }
  336.       case PIPE_VIDEO_FORMAT_VC1: {
  337.          assert((r & 0xff) == 0xac);
  338.          dec->fw_sizes = (0x3ac<<16) | (r - 0x3ac);
  339.          break;
  340.       }
  341.       case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
  342.          assert((r & 0xff) == 0x70);
  343.          dec->fw_sizes = (0x370<<16) | (r - 0x370);
  344.          break;
  345.       }
  346.       default:
  347.          return 1;
  348.    }
  349.    munmap(dec->fw_bo->map, dec->fw_bo->size);
  350.    dec->fw_bo->map = NULL;
  351.    return 0;
  352. }
  353.  
  354. static int
  355. firmware_present(struct pipe_screen *pscreen, enum pipe_video_profile profile)
  356. {
  357.    struct nouveau_screen *screen = nouveau_screen(pscreen);
  358.    int chipset = screen->device->chipset;
  359.    int vp3 = chipset < 0xa3 || chipset == 0xaa || chipset == 0xac;
  360.    int vp5 = chipset >= 0xd0;
  361.    int ret;
  362.  
  363.    /* For all chipsets, try to create a BSP objects. Assume that if firmware
  364.     * is present for it, firmware is also present for VP/PPP */
  365.    if (!(screen->firmware_info.profiles_checked & 1)) {
  366.       struct nouveau_object *channel = NULL, *bsp = NULL;
  367.       struct nv04_fifo nv04_data = {.vram = 0xbeef0201, .gart = 0xbeef0202};
  368.       struct nvc0_fifo nvc0_args = {};
  369.       struct nve0_fifo nve0_args = {.engine = NVE0_FIFO_ENGINE_BSP};
  370.       void *data = NULL;
  371.       int size, oclass;
  372.       if (chipset < 0xc0)
  373.          oclass = 0x85b1;
  374.       else if (chipset < 0xe0)
  375.          oclass = 0x90b1;
  376.       else
  377.          oclass = 0x95b1;
  378.  
  379.       if (chipset < 0xc0) {
  380.          data = &nv04_data;
  381.          size = sizeof(nv04_data);
  382.       } else if (chipset < 0xe0) {
  383.          data = &nvc0_args;
  384.          size = sizeof(nvc0_args);
  385.       } else {
  386.          data = &nve0_args;
  387.          size = sizeof(nve0_args);
  388.       }
  389.  
  390.       /* kepler must have its own channel, so just do this for everyone */
  391.       nouveau_object_new(&screen->device->object, 0,
  392.                          NOUVEAU_FIFO_CHANNEL_CLASS,
  393.                          data, size, &channel);
  394.  
  395.       if (channel) {
  396.          nouveau_object_new(channel, 0, oclass, NULL, 0, &bsp);
  397.          if (bsp)
  398.             screen->firmware_info.profiles_present |= 1;
  399.          nouveau_object_del(&bsp);
  400.          nouveau_object_del(&channel);
  401.       }
  402.       screen->firmware_info.profiles_checked |= 1;
  403.    }
  404.  
  405.    if (!(screen->firmware_info.profiles_present & 1))
  406.       return 0;
  407.  
  408.    /* For vp3/vp4 chipsets, make sure that the relevant firmware is present */
  409.    if (!vp5 && !(screen->firmware_info.profiles_checked & (1 << profile))) {
  410.       char path[PATH_MAX];
  411.       struct stat s;
  412.       if (vp3)
  413.          vp3_getpath(profile, path);
  414.       else
  415.          vp4_getpath(profile, path);
  416.       ret = stat(path, &s);
  417.       if (!ret && s.st_size > 1000)
  418.          screen->firmware_info.profiles_present |= (1 << profile);
  419.       screen->firmware_info.profiles_checked |= (1 << profile);
  420.    }
  421.  
  422.    return vp5 || (screen->firmware_info.profiles_present & (1 << profile));
  423. }
  424.  
  425. int
  426. nouveau_vp3_screen_get_video_param(struct pipe_screen *pscreen,
  427.                                    enum pipe_video_profile profile,
  428.                                    enum pipe_video_entrypoint entrypoint,
  429.                                    enum pipe_video_cap param)
  430. {
  431.    int chipset = nouveau_screen(pscreen)->device->chipset;
  432.    int vp3 = chipset < 0xa3 || chipset == 0xaa || chipset == 0xac;
  433.    int vp5 = chipset >= 0xd0;
  434.    enum pipe_video_format codec = u_reduce_video_profile(profile);
  435.    switch (param) {
  436.    case PIPE_VIDEO_CAP_SUPPORTED:
  437.       /* VP3 does not support MPEG4, VP4+ do. */
  438.       return entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM &&
  439.          profile >= PIPE_VIDEO_PROFILE_MPEG1 &&
  440.          (!vp3 || codec != PIPE_VIDEO_FORMAT_MPEG4) &&
  441.          firmware_present(pscreen, profile);
  442.    case PIPE_VIDEO_CAP_NPOT_TEXTURES:
  443.       return 1;
  444.    case PIPE_VIDEO_CAP_MAX_WIDTH:
  445.    case PIPE_VIDEO_CAP_MAX_HEIGHT:
  446.       return vp5 ? 4096 : 2048;
  447.    case PIPE_VIDEO_CAP_PREFERED_FORMAT:
  448.       return PIPE_FORMAT_NV12;
  449.    case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
  450.    case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
  451.       return true;
  452.    case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
  453.       return false;
  454.    case PIPE_VIDEO_CAP_MAX_LEVEL:
  455.       switch (profile) {
  456.       case PIPE_VIDEO_PROFILE_MPEG1:
  457.          return 0;
  458.       case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
  459.       case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
  460.          return 3;
  461.       case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE:
  462.          return 3;
  463.       case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE:
  464.          return 5;
  465.       case PIPE_VIDEO_PROFILE_VC1_SIMPLE:
  466.          return 1;
  467.       case PIPE_VIDEO_PROFILE_VC1_MAIN:
  468.          return 2;
  469.       case PIPE_VIDEO_PROFILE_VC1_ADVANCED:
  470.          return 4;
  471.       case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
  472.       case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
  473.       case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
  474.          return 41;
  475.       default:
  476.          debug_printf("unknown video profile: %d\n", profile);
  477.          return 0;
  478.       }
  479.    default:
  480.       debug_printf("unknown video param: %d\n", param);
  481.       return 0;
  482.    }
  483. }
  484.  
  485. boolean
  486. nouveau_vp3_screen_video_supported(struct pipe_screen *screen,
  487.                                    enum pipe_format format,
  488.                                    enum pipe_video_profile profile,
  489.                                    enum pipe_video_entrypoint entrypoint)
  490. {
  491.    if (profile != PIPE_VIDEO_PROFILE_UNKNOWN)
  492.       return format == PIPE_FORMAT_NV12;
  493.  
  494.    return vl_video_buffer_is_format_supported(screen, format, profile, entrypoint);
  495. }
  496.