"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c" (16 Sep 2020, 7187 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "nv98_video_bsp.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright 2011-2013 Maarten Lankhorst, Ilia Mirkin
    3  *
    4  * Permission is hereby granted, free of charge, to any person obtaining a
    5  * copy of this software and associated documentation files (the "Software"),
    6  * to deal in the Software without restriction, including without limitation
    7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    8  * and/or sell copies of the Software, and to permit persons to whom the
    9  * Software is furnished to do so, subject to the following conditions:
   10  *
   11  * The above copyright notice and this permission notice shall be included in
   12  * all copies or substantial portions of the Software.
   13  *
   14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
   18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
   19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
   20  * OTHER DEALINGS IN THE SOFTWARE.
   21  */
   22 
   23 #include "nv50/nv98_video.h"
   24 
   25 #if NOUVEAU_VP3_DEBUG_FENCE
   26 static void dump_comm_bsp(struct comm *comm)
   27 {
   28    unsigned idx = comm->bsp_cur_index & 0xf;
   29    debug_printf("Cur seq: %x, bsp byte ofs: %x\n", comm->bsp_cur_index, comm->byte_ofs);
   30    debug_printf("Status: %08x, pos: %08x\n", comm->status[idx], comm->pos[idx]);
   31 }
   32 #endif
   33 
   34 unsigned
   35 nv98_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
   36                  struct nouveau_vp3_video_buffer *target,
   37                  unsigned comm_seq, unsigned num_buffers,
   38                  const void *const *data, const unsigned *num_bytes,
   39                  unsigned *vp_caps, unsigned *is_ref,
   40                  struct nouveau_vp3_video_buffer *refs[16])
   41 {
   42    struct nouveau_pushbuf *push = dec->pushbuf[0];
   43    enum pipe_video_format codec = u_reduce_video_profile(dec->base.profile);
   44    uint32_t bsp_addr, comm_addr, inter_addr;
   45    uint32_t slice_size, bucket_size, ring_size, bsp_size;
   46    uint32_t caps, i;
   47    int ret;
   48    struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];
   49    struct nouveau_bo *inter_bo = dec->inter_bo[comm_seq & 1];
   50    struct nouveau_pushbuf_refn bo_refs[] = {
   51       { bsp_bo, NOUVEAU_BO_RD | NOUVEAU_BO_VRAM },
   52       { inter_bo, NOUVEAU_BO_WR | NOUVEAU_BO_VRAM },
   53 #if NOUVEAU_VP3_DEBUG_FENCE
   54       { dec->fence_bo, NOUVEAU_BO_WR | NOUVEAU_BO_GART },
   55 #endif
   56       { dec->bitplane_bo, NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM },
   57    };
   58    int num_refs = ARRAY_SIZE(bo_refs);
   59 
   60    if (!dec->bitplane_bo)
   61       num_refs--;
   62 
   63    bsp_size = NOUVEAU_VP3_BSP_RESERVED_SIZE;
   64    for (i = 0; i < num_buffers; i++)
   65       bsp_size += num_bytes[i];
   66    bsp_size += 256; /* the 4 end markers */
   67 
   68    if (!bsp_bo || bsp_size > bsp_bo->size) {
   69       struct nouveau_bo *tmp_bo = NULL;
   70 
   71       /* round up to the nearest mb */
   72       bsp_size += (1 << 20) - 1;
   73       bsp_size &= ~((1 << 20) - 1);
   74 
   75       ret = nouveau_bo_new(dec->client->device, NOUVEAU_BO_VRAM, 0, bsp_size, NULL, &tmp_bo);
   76       if (ret) {
   77          debug_printf("reallocating bsp %u -> %u failed with %i\n",
   78                       bsp_bo ? (unsigned)bsp_bo->size : 0, bsp_size, ret);
   79          return -1;
   80       }
   81       nouveau_bo_ref(NULL, &bsp_bo);
   82       bo_refs[0].bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH] = bsp_bo = tmp_bo;
   83    }
   84 
   85    if (!inter_bo || bsp_bo->size * 4 > inter_bo->size) {
   86       struct nouveau_bo *tmp_bo = NULL;
   87 
   88       ret = nouveau_bo_new(dec->client->device, NOUVEAU_BO_VRAM, 0, bsp_bo->size * 4, NULL, &tmp_bo);
   89       if (ret) {
   90          debug_printf("reallocating inter %u -> %u failed with %i\n",
   91                       inter_bo ? (unsigned)inter_bo->size : 0, (unsigned)bsp_bo->size * 4, ret);
   92          return -1;
   93       }
   94       nouveau_bo_ref(NULL, &inter_bo);
   95       bo_refs[1].bo = dec->inter_bo[comm_seq & 1] = inter_bo = tmp_bo;
   96    }
   97 
   98    ret = nouveau_bo_map(bsp_bo, NOUVEAU_BO_WR, dec->client);
   99    if (ret) {
  100       debug_printf("map failed: %i %s\n", ret, strerror(-ret));
  101       return -1;
  102    }
  103 
  104    nouveau_vp3_bsp_begin(dec);
  105    nouveau_vp3_bsp_next(dec, num_buffers, data, num_bytes);
  106    caps = nouveau_vp3_bsp_end(dec, desc);
  107 
  108    nouveau_vp3_vp_caps(dec, desc, target, comm_seq, vp_caps, is_ref, refs);
  109 
  110    nouveau_pushbuf_space(push, 32, num_refs, 0);
  111    nouveau_pushbuf_refn(push, bo_refs, num_refs);
  112 
  113    bsp_addr = bsp_bo->offset >> 8;
  114    inter_addr = inter_bo->offset >> 8;
  115 
  116 #if NOUVEAU_VP3_DEBUG_FENCE
  117    memset(dec->comm, 0, 0x200);
  118    comm_addr = (dec->fence_bo->offset + COMM_OFFSET) >> 8;
  119 #else
  120    comm_addr = bsp_addr + (COMM_OFFSET>>8);
  121 #endif
  122 
  123    BEGIN_NV04(push, SUBC_BSP(0x700), 5);
  124    PUSH_DATA (push, caps); // 700 cmd
  125    PUSH_DATA (push, bsp_addr + 1); // 704 strparm_bsp
  126    PUSH_DATA (push, bsp_addr + 7); // 708 str addr
  127    PUSH_DATA (push, comm_addr); // 70c comm
  128    PUSH_DATA (push, comm_seq); // 710 seq
  129 
  130    if (codec != PIPE_VIDEO_FORMAT_MPEG4_AVC) {
  131       u32 bitplane_addr;
  132       int mpeg12 = (codec == PIPE_VIDEO_FORMAT_MPEG12);
  133 
  134       bitplane_addr = dec->bitplane_bo->offset >> 8;
  135 
  136       nouveau_vp3_inter_sizes(dec, 1, &slice_size, &bucket_size, &ring_size);
  137       BEGIN_NV04(push, SUBC_BSP(0x400), mpeg12 ? 5 : 7);
  138       PUSH_DATA (push, bsp_addr); // 400 picparm addr
  139       PUSH_DATA (push, inter_addr); // 404 interparm addr
  140       PUSH_DATA (push, inter_addr + slice_size + bucket_size); // 408 interdata addr
  141       PUSH_DATA (push, ring_size << 8); // 40c interdata_size
  142       if (!mpeg12) {
  143          PUSH_DATA (push, bitplane_addr); // 410 BITPLANE_DATA
  144          PUSH_DATA (push, 0x400); // 414 BITPLANE_DATA_SIZE
  145       }
  146       PUSH_DATA (push, 0); // dma idx
  147    } else {
  148       nouveau_vp3_inter_sizes(dec, desc.h264->slice_count, &slice_size, &bucket_size, &ring_size);
  149       BEGIN_NV04(push, SUBC_BSP(0x400), 8);
  150       PUSH_DATA (push, bsp_addr); // 400 picparm addr
  151       PUSH_DATA (push, inter_addr); // 404 interparm addr
  152       PUSH_DATA (push, slice_size << 8); // 408 interparm size?
  153       PUSH_DATA (push, inter_addr + slice_size + bucket_size); // 40c interdata addr
  154       PUSH_DATA (push, ring_size << 8); // 410 interdata size
  155       PUSH_DATA (push, inter_addr + slice_size); // 414 bucket?
  156       PUSH_DATA (push, bucket_size << 8); // 418 bucket size? unshifted..
  157       PUSH_DATA (push, 0); // 41c targets
  158       // TODO: Double check 414 / 418 with nvidia trace
  159    }
  160 
  161 #if NOUVEAU_VP3_DEBUG_FENCE
  162    BEGIN_NV04(push, SUBC_BSP(0x240), 3);
  163    PUSH_DATAh(push, dec->fence_bo->offset);
  164    PUSH_DATA (push, dec->fence_bo->offset);
  165    PUSH_DATA (push, dec->fence_seq);
  166 
  167    BEGIN_NV04(push, SUBC_BSP(0x300), 1);
  168    PUSH_DATA (push, 1);
  169    PUSH_KICK (push);
  170 
  171    {
  172       unsigned spin = 0;
  173       do {
  174          usleep(100);
  175          if ((spin++ & 0xff) == 0xff) {
  176             debug_printf("b%u: %u\n", dec->fence_seq, dec->fence_map[0]);
  177             dump_comm_bsp(dec->comm);
  178          }
  179       } while (dec->fence_seq > dec->fence_map[0]);
  180    }
  181 
  182    dump_comm_bsp(dec->comm);
  183    return dec->comm->status[comm_seq & 0xf];
  184 #else
  185    BEGIN_NV04(push, SUBC_BSP(0x300), 1);
  186    PUSH_DATA (push, 0);
  187    PUSH_KICK (push);
  188    return 2;
  189 #endif
  190 }