Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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. #include <sys/mman.h>
  25.  
  26. #if NOUVEAU_VP3_DEBUG_FENCE
  27. static void dump_comm_vp(struct nouveau_vp3_decoder *dec, struct comm *comm, u32 comm_seq,
  28.                          struct nouveau_bo *inter_bo, unsigned slice_size)
  29. {
  30.         unsigned i, idx = comm->pvp_cur_index & 0xf;
  31.         debug_printf("Status: %08x, stage: %08x\n", comm->status_vp[idx], comm->pvp_stage);
  32. #if 0
  33.         debug_printf("Acked byte ofs: %x, bsp byte ofs: %x\n", comm->acked_byte_ofs, comm->byte_ofs);
  34.         debug_printf("Irq/parse indexes: %i %i\n", comm->irq_index, comm->parse_endpos_index);
  35.  
  36.         for (i = 0; i != comm->irq_index; ++i)
  37.                 debug_printf("irq[%i] = { @ %08x -> %04x }\n", i, comm->irq_pos[i], comm->irq_470[i]);
  38.         for (i = 0; i != comm->parse_endpos_index; ++i)
  39.                 debug_printf("parse_endpos[%i] = { @ %08x}\n", i, comm->parse_endpos[i]);
  40. #endif
  41.         debug_printf("mb_y = %u\n", comm->mb_y[idx]);
  42.         if (comm->status_vp[idx] <= 1)
  43.                 return;
  44.  
  45.         if ((comm->pvp_stage & 0xff) != 0xff) {
  46.                 unsigned *map;
  47.                 int ret = nouveau_bo_map(inter_bo, NOUVEAU_BO_RD|NOUVEAU_BO_NOBLOCK, dec->client);
  48.                 assert(ret >= 0);
  49.                 map = inter_bo->map;
  50.                 for (i = 0; i < comm->byte_ofs + slice_size; i += 0x10) {
  51.                         debug_printf("%05x: %08x %08x %08x %08x\n", i, map[i/4], map[i/4+1], map[i/4+2], map[i/4+3]);
  52.                 }
  53.                 munmap(inter_bo->map, inter_bo->size);
  54.                 inter_bo->map = NULL;
  55.         }
  56.         assert((comm->pvp_stage & 0xff) == 0xff);
  57. }
  58. #endif
  59.  
  60. static void
  61. nv98_decoder_kick_ref(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video_buffer *target)
  62. {
  63.    dec->refs[target->valid_ref].last_used = 0;
  64. //   debug_printf("Unreffed %p\n", target);
  65. }
  66.  
  67. void
  68. nv98_decoder_vp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
  69.                 struct nouveau_vp3_video_buffer *target, unsigned comm_seq,
  70.                 unsigned caps, unsigned is_ref,
  71.                 struct nouveau_vp3_video_buffer *refs[16])
  72. {
  73.    struct nouveau_pushbuf *push = dec->pushbuf[1];
  74.    uint32_t bsp_addr, comm_addr, inter_addr, ucode_addr, pic_addr[17], last_addr, null_addr;
  75.    uint32_t slice_size, bucket_size, ring_size, i;
  76.    enum pipe_video_format codec = u_reduce_video_profile(dec->base.profile);
  77.    struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];
  78.    struct nouveau_bo *inter_bo = dec->inter_bo[comm_seq & 1];
  79.    u32 fence_extra = 0, codec_extra = 0;
  80.    struct nouveau_pushbuf_refn bo_refs[] = {
  81.       { inter_bo, NOUVEAU_BO_WR | NOUVEAU_BO_VRAM },
  82.       { dec->ref_bo, NOUVEAU_BO_WR | NOUVEAU_BO_VRAM },
  83.       { bsp_bo, NOUVEAU_BO_RD | NOUVEAU_BO_VRAM },
  84. #if NOUVEAU_VP3_DEBUG_FENCE
  85.       { dec->fence_bo, NOUVEAU_BO_WR | NOUVEAU_BO_GART },
  86. #endif
  87.       { dec->fw_bo, NOUVEAU_BO_RD | NOUVEAU_BO_VRAM },
  88.    };
  89.    int num_refs = sizeof(bo_refs)/sizeof(*bo_refs) - !dec->fw_bo;
  90.  
  91. #if NOUVEAU_VP3_DEBUG_FENCE
  92.    fence_extra = 4;
  93. #endif
  94.  
  95.    if (codec == PIPE_VIDEO_FORMAT_MPEG4_AVC) {
  96.       nouveau_vp3_inter_sizes(dec, desc.h264->slice_count, &slice_size, &bucket_size, &ring_size);
  97.       codec_extra += 2;
  98.    } else
  99.       nouveau_vp3_inter_sizes(dec, 1, &slice_size, &bucket_size, &ring_size);
  100.  
  101.    if (dec->base.max_references > 2)
  102.       codec_extra += 1 + (dec->base.max_references - 2);
  103.  
  104.    pic_addr[16] = nouveau_vp3_video_addr(dec, target) >> 8;
  105.    last_addr = null_addr = nouveau_vp3_video_addr(dec, NULL) >> 8;
  106.  
  107.    for (i = 0; i < dec->base.max_references; ++i) {
  108.       if (!refs[i])
  109.          pic_addr[i] = last_addr;
  110.       else if (dec->refs[refs[i]->valid_ref].vidbuf == refs[i])
  111.          last_addr = pic_addr[i] = nouveau_vp3_video_addr(dec, refs[i]) >> 8;
  112.       else
  113.          pic_addr[i] = null_addr;
  114.    }
  115.    if (!is_ref && (dec->refs[target->valid_ref].decoded_top && dec->refs[target->valid_ref].decoded_bottom))
  116.       nv98_decoder_kick_ref(dec, target);
  117.  
  118.    nouveau_pushbuf_space(push, 8 + 3 * (codec != PIPE_VIDEO_FORMAT_MPEG12) +
  119.               6 + codec_extra + fence_extra + 2, num_refs, 0);
  120.  
  121.    nouveau_pushbuf_refn(push, bo_refs, num_refs);
  122.  
  123.    bsp_addr = bsp_bo->offset >> 8;
  124. #if NOUVEAU_VP3_DEBUG_FENCE
  125.    comm_addr = (dec->fence_bo->offset + COMM_OFFSET)>>8;
  126. #else
  127.    comm_addr = bsp_addr + (COMM_OFFSET>>8);
  128. #endif
  129.    inter_addr = inter_bo->offset >> 8;
  130.    if (dec->fw_bo)
  131.       ucode_addr = dec->fw_bo->offset >> 8;
  132.    else
  133.       ucode_addr = 0;
  134.  
  135.    BEGIN_NV04(push, SUBC_VP(0x700), 7);
  136.    PUSH_DATA (push, caps); // 700
  137.    PUSH_DATA (push, comm_seq); // 704
  138.    PUSH_DATA (push, 0); // 708 fuc targets, ignored for nv98
  139.    PUSH_DATA (push, dec->fw_sizes); // 70c
  140.    PUSH_DATA (push, bsp_addr+(VP_OFFSET>>8)); // 710 picparm_addr
  141.    PUSH_DATA (push, inter_addr); // 714 inter_parm
  142.    PUSH_DATA (push, inter_addr + slice_size + bucket_size); // 718 inter_data_ofs
  143.  
  144.    if (bucket_size) {
  145.       uint64_t tmpimg_addr = dec->ref_bo->offset + dec->ref_stride * (dec->base.max_references+2);
  146.  
  147.       BEGIN_NV04(push, SUBC_VP(0x71c), 2);
  148.       PUSH_DATA (push, tmpimg_addr >> 8); // 71c
  149.       PUSH_DATA (push, inter_addr + slice_size); // 720 bucket_ofs
  150.    }
  151.  
  152.    BEGIN_NV04(push, SUBC_VP(0x724), 5);
  153.    PUSH_DATA (push, comm_addr); // 724
  154.    PUSH_DATA (push, ucode_addr); // 728
  155.    PUSH_DATA (push, pic_addr[16]); // 734
  156.    PUSH_DATA (push, pic_addr[0]); // 72c
  157.    PUSH_DATA (push, pic_addr[1]); // 730
  158.  
  159.    if (dec->base.max_references > 2) {
  160.       int i;
  161.  
  162.       BEGIN_NV04(push, SUBC_VP(0x400), dec->base.max_references - 2);
  163.       for (i = 2; i < dec->base.max_references; ++i) {
  164.          assert(0x400 + (i - 2) * 4 < 0x438);
  165.          PUSH_DATA (push, pic_addr[i]);
  166.       }
  167.    }
  168.  
  169.    if (codec == PIPE_VIDEO_FORMAT_MPEG4_AVC) {
  170.       BEGIN_NV04(push, SUBC_VP(0x438), 1);
  171.       PUSH_DATA (push, desc.h264->slice_count);
  172.    }
  173.  
  174.    //debug_printf("Decoding %08lx with %08lx and %08lx\n", pic_addr[16], pic_addr[0], pic_addr[1]);
  175.  
  176. #if NOUVEAU_VP3_DEBUG_FENCE
  177.    BEGIN_NV04(push, SUBC_VP(0x240), 3);
  178.    PUSH_DATAh(push, (dec->fence_bo->offset + 0x10));
  179.    PUSH_DATA (push, (dec->fence_bo->offset + 0x10));
  180.    PUSH_DATA (push, dec->fence_seq);
  181.  
  182.    BEGIN_NV04(push, SUBC_VP(0x300), 1);
  183.    PUSH_DATA (push, 1);
  184.    PUSH_KICK(push);
  185.  
  186.    {
  187.       unsigned spin = 0;
  188.       do {
  189.          usleep(100);
  190.          if ((spin++ & 0xff) == 0xff) {
  191.             debug_printf("v%u: %u\n", dec->fence_seq, dec->fence_map[4]);
  192.             dump_comm_vp(dec, dec->comm, comm_seq, inter_bo, slice_size << 8);
  193.          }
  194.       } while (dec->fence_seq > dec->fence_map[4]);
  195.    }
  196.    dump_comm_vp(dec, dec->comm, comm_seq, inter_bo, slice_size << 8);
  197. #else
  198.    BEGIN_NV04(push, SUBC_VP(0x300), 1);
  199.    PUSH_DATA (push, 0);
  200.    PUSH_KICK (push);
  201. #endif
  202. }
  203.