Path: blob/21.2-virgl/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c
4574 views
/*1* Copyright 2011-2013 Maarten Lankhorst2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice shall be included in11* all copies or substantial portions of the Software.12*13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL16* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR17* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,18* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR19* OTHER DEALINGS IN THE SOFTWARE.20*/2122#include "nvc0/nvc0_video.h"23#include <sys/mman.h>2425#if NOUVEAU_VP3_DEBUG_FENCE26static void dump_comm_vp(struct nouveau_vp3_decoder *dec, struct comm *comm, u32 comm_seq,27struct nouveau_bo *inter_bo, unsigned slice_size)28{29unsigned i, idx = comm->pvp_cur_index & 0xf;30debug_printf("Status: %08x, stage: %08x\n", comm->status_vp[idx], comm->pvp_stage);31#if 032debug_printf("Acked byte ofs: %x, bsp byte ofs: %x\n", comm->acked_byte_ofs, comm->byte_ofs);33debug_printf("Irq/parse indexes: %i %i\n", comm->irq_index, comm->parse_endpos_index);3435for (i = 0; i != comm->irq_index; ++i)36debug_printf("irq[%i] = { @ %08x -> %04x }\n", i, comm->irq_pos[i], comm->irq_470[i]);37for (i = 0; i != comm->parse_endpos_index; ++i)38debug_printf("parse_endpos[%i] = { @ %08x}\n", i, comm->parse_endpos[i]);39#endif40debug_printf("mb_y = %u\n", comm->mb_y[idx]);41if (comm->status_vp[idx] <= 1)42return;4344if ((comm->pvp_stage & 0xff) != 0xff) {45unsigned *map;46int ret = nouveau_bo_map(inter_bo, NOUVEAU_BO_RD|NOUVEAU_BO_NOBLOCK, dec->client);47assert(ret >= 0);48map = inter_bo->map;49for (i = 0; i < comm->byte_ofs + slice_size; i += 0x10) {50debug_printf("%05x: %08x %08x %08x %08x\n", i, map[i/4], map[i/4+1], map[i/4+2], map[i/4+3]);51}52munmap(inter_bo->map, inter_bo->size);53inter_bo->map = NULL;54}55assert((comm->pvp_stage & 0xff) == 0xff);56}57#endif5859static void60nvc0_decoder_kick_ref(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video_buffer *target)61{62dec->refs[target->valid_ref].last_used = 0;63// debug_printf("Unreffed %p\n", target);64}6566void67nvc0_decoder_vp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,68struct nouveau_vp3_video_buffer *target, unsigned comm_seq,69unsigned caps, unsigned is_ref,70struct nouveau_vp3_video_buffer *refs[16])71{72struct nouveau_pushbuf *push = dec->pushbuf[1];73uint32_t bsp_addr, comm_addr, inter_addr, ucode_addr, pic_addr[17], last_addr, null_addr;74uint32_t slice_size, bucket_size, ring_size, i;75enum pipe_video_format codec = u_reduce_video_profile(dec->base.profile);76struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];77struct nouveau_bo *inter_bo = dec->inter_bo[comm_seq & 1];78u32 codec_extra = 0;79struct nouveau_pushbuf_refn bo_refs[] = {80{ inter_bo, NOUVEAU_BO_WR | NOUVEAU_BO_VRAM },81{ dec->ref_bo, NOUVEAU_BO_WR | NOUVEAU_BO_VRAM },82{ bsp_bo, NOUVEAU_BO_RD | NOUVEAU_BO_VRAM },83#if NOUVEAU_VP3_DEBUG_FENCE84{ dec->fence_bo, NOUVEAU_BO_WR | NOUVEAU_BO_GART },85#endif86{ dec->fw_bo, NOUVEAU_BO_RD | NOUVEAU_BO_VRAM },87};88int num_refs = ARRAY_SIZE(bo_refs) - !dec->fw_bo;8990if (codec == PIPE_VIDEO_FORMAT_MPEG4_AVC) {91nouveau_vp3_inter_sizes(dec, desc.h264->slice_count, &slice_size, &bucket_size, &ring_size);92codec_extra += 2;93} else94nouveau_vp3_inter_sizes(dec, 1, &slice_size, &bucket_size, &ring_size);9596if (dec->base.max_references > 2)97codec_extra += 1 + (dec->base.max_references - 2);9899pic_addr[16] = nouveau_vp3_video_addr(dec, target) >> 8;100last_addr = null_addr = nouveau_vp3_video_addr(dec, NULL) >> 8;101102for (i = 0; i < dec->base.max_references; ++i) {103if (!refs[i])104pic_addr[i] = last_addr;105else if (dec->refs[refs[i]->valid_ref].vidbuf == refs[i])106last_addr = pic_addr[i] = nouveau_vp3_video_addr(dec, refs[i]) >> 8;107else108pic_addr[i] = null_addr;109}110if (!is_ref && (dec->refs[target->valid_ref].decoded_top && dec->refs[target->valid_ref].decoded_bottom))111nvc0_decoder_kick_ref(dec, target);112113nouveau_pushbuf_space(push, 32 + codec_extra, num_refs, 0);114115nouveau_pushbuf_refn(push, bo_refs, num_refs);116117bsp_addr = bsp_bo->offset >> 8;118#if NOUVEAU_VP3_DEBUG_FENCE119comm_addr = (dec->fence_bo->offset + COMM_OFFSET)>>8;120#else121comm_addr = bsp_addr + (COMM_OFFSET>>8);122#endif123inter_addr = inter_bo->offset >> 8;124if (dec->fw_bo)125ucode_addr = dec->fw_bo->offset >> 8;126else127ucode_addr = 0;128129BEGIN_NVC0(push, SUBC_VP(0x700), 7);130PUSH_DATA (push, caps); // 700131PUSH_DATA (push, comm_seq); // 704132PUSH_DATA (push, 0); // 708 fuc targets, ignored for nvc0133PUSH_DATA (push, dec->fw_sizes); // 70c134PUSH_DATA (push, bsp_addr+(VP_OFFSET>>8)); // 710 picparm_addr135PUSH_DATA (push, inter_addr); // 714 inter_parm136PUSH_DATA (push, inter_addr + slice_size + bucket_size); // 718 inter_data_ofs137138if (bucket_size) {139uint64_t tmpimg_addr = dec->ref_bo->offset + dec->ref_stride * (dec->base.max_references+2);140141BEGIN_NVC0(push, SUBC_VP(0x71c), 2);142PUSH_DATA (push, tmpimg_addr >> 8); // 71c143PUSH_DATA (push, inter_addr + slice_size); // 720 bucket_ofs144}145146BEGIN_NVC0(push, SUBC_VP(0x724), 5);147PUSH_DATA (push, comm_addr); // 724148PUSH_DATA (push, ucode_addr); // 728149PUSH_DATA (push, pic_addr[16]); // 734150PUSH_DATA (push, pic_addr[0]); // 72c151PUSH_DATA (push, pic_addr[1]); // 730152153if (dec->base.max_references > 2) {154int i;155156BEGIN_NVC0(push, SUBC_VP(0x400), dec->base.max_references - 2);157for (i = 2; i < dec->base.max_references; ++i) {158assert(0x400 + (i - 2) * 4 < 0x438);159PUSH_DATA (push, pic_addr[i]);160}161}162163if (codec == PIPE_VIDEO_FORMAT_MPEG4_AVC) {164BEGIN_NVC0(push, SUBC_VP(0x438), 1);165PUSH_DATA (push, desc.h264->slice_count);166}167168//debug_printf("Decoding %08lx with %08lx and %08lx\n", pic_addr[16], pic_addr[0], pic_addr[1]);169170#if NOUVEAU_VP3_DEBUG_FENCE171BEGIN_NVC0(push, SUBC_VP(0x240), 3);172PUSH_DATAh(push, (dec->fence_bo->offset + 0x10));173PUSH_DATA (push, (dec->fence_bo->offset + 0x10));174PUSH_DATA (push, dec->fence_seq);175176BEGIN_NVC0(push, SUBC_VP(0x300), 1);177PUSH_DATA (push, 1);178PUSH_KICK(push);179180{181unsigned spin = 0;182do {183usleep(100);184if ((spin++ & 0xff) == 0xff) {185debug_printf("v%u: %u\n", dec->fence_seq, dec->fence_map[4]);186dump_comm_vp(dec, dec->comm, comm_seq, inter_bo, slice_size << 8);187}188} while (dec->fence_seq > dec->fence_map[4]);189}190dump_comm_vp(dec, dec->comm, comm_seq, inter_bo, slice_size << 8);191#else192BEGIN_NVC0(push, SUBC_VP(0x300), 1);193PUSH_DATA (push, 0);194PUSH_KICK (push);195#endif196}197198199