Path: blob/21.2-virgl/src/gallium/drivers/nouveau/nouveau_vp3_video_bsp.c
4570 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 "nouveau_vp3_video.h"2324struct strparm_bsp {25uint32_t w0[4]; // bits 0-23 length, bits 24-31 addr_hi26uint32_t w1[4]; // bit 8-24 addr_lo27uint32_t unk20; // should be idx * 0x8000000, bitstream offset28uint32_t do_crypto_crap; // set to 029};3031struct mpeg12_picparm_bsp {32uint16_t width;33uint16_t height;34uint8_t picture_structure;35uint8_t picture_coding_type;36uint8_t intra_dc_precision;37uint8_t frame_pred_frame_dct;38uint8_t concealment_motion_vectors;39uint8_t intra_vlc_format;40uint16_t pad;41uint8_t f_code[2][2];42};4344struct mpeg4_picparm_bsp {45uint16_t width;46uint16_t height;47uint8_t vop_time_increment_size;48uint8_t interlaced;49uint8_t resync_marker_disable;50};5152struct vc1_picparm_bsp {53uint16_t width;54uint16_t height;55uint8_t profile; // 04 0 simple, 1 main, 2 advanced56uint8_t postprocflag; // 0557uint8_t pulldown; // 0658uint8_t interlaced; // 0759uint8_t tfcntrflag; // 0860uint8_t finterpflag; // 0961uint8_t psf; // 0a62uint8_t pad; // 0b63uint8_t multires; // 0c64uint8_t syncmarker; // 0d65uint8_t rangered; // 0e66uint8_t maxbframes; // 0f67uint8_t dquant; // 1068uint8_t panscan_flag; // 1169uint8_t refdist_flag; // 1270uint8_t quantizer; // 1371uint8_t extended_mv; // 1472uint8_t extended_dmv; // 1573uint8_t overlap; // 1674uint8_t vstransform; // 1775};7677struct h264_picparm_bsp {78// 0079uint32_t unk00;80// 0481uint32_t log2_max_frame_num_minus4; // 04 checked82uint32_t pic_order_cnt_type; // 08 checked83uint32_t log2_max_pic_order_cnt_lsb_minus4; // 0c checked84uint32_t delta_pic_order_always_zero_flag; // 10, or unknown8586uint32_t frame_mbs_only_flag; // 14, always 1?87uint32_t direct_8x8_inference_flag; // 18, always 1?88uint32_t width_mb; // 1c checked89uint32_t height_mb; // 20 checked90// 2491//struct picparm292uint32_t entropy_coding_mode_flag; // 00, checked93uint32_t pic_order_present_flag; // 04 checked94uint32_t unk; // 08 seems to be 0?95uint32_t pad1; // 0c seems to be 0?96uint32_t pad2; // 10 always 0 ?97uint32_t num_ref_idx_l0_active_minus1; // 14 always 0?98uint32_t num_ref_idx_l1_active_minus1; // 18 always 0?99uint32_t weighted_pred_flag; // 1c checked100uint32_t weighted_bipred_idc; // 20 checked101uint32_t pic_init_qp_minus26; // 24 checked102uint32_t deblocking_filter_control_present_flag; // 28 always 1?103uint32_t redundant_pic_cnt_present_flag; // 2c always 0?104uint32_t transform_8x8_mode_flag; // 30 checked105uint32_t mb_adaptive_frame_field_flag; // 34 checked-ish106uint8_t field_pic_flag; // 38 checked107uint8_t bottom_field_flag; // 39 checked108uint8_t real_pad[0x1b]; // XX why?109};110111static uint32_t112nouveau_vp3_fill_picparm_mpeg12_bsp(struct nouveau_vp3_decoder *dec,113struct pipe_mpeg12_picture_desc *desc,114char *map)115{116struct mpeg12_picparm_bsp *pic_bsp = (struct mpeg12_picparm_bsp *)map;117int i;118pic_bsp->width = dec->base.width;119pic_bsp->height = dec->base.height;120pic_bsp->picture_structure = desc->picture_structure;121pic_bsp->picture_coding_type = desc->picture_coding_type;122pic_bsp->intra_dc_precision = desc->intra_dc_precision;123pic_bsp->frame_pred_frame_dct = desc->frame_pred_frame_dct;124pic_bsp->concealment_motion_vectors = desc->concealment_motion_vectors;125pic_bsp->intra_vlc_format = desc->intra_vlc_format;126pic_bsp->pad = 0;127for (i = 0; i < 4; ++i)128pic_bsp->f_code[i/2][i%2] = desc->f_code[i/2][i%2] + 1; // FU129130return (desc->num_slices << 4) | (dec->base.profile != PIPE_VIDEO_PROFILE_MPEG1);131}132133static uint32_t134nouveau_vp3_fill_picparm_mpeg4_bsp(struct nouveau_vp3_decoder *dec,135struct pipe_mpeg4_picture_desc *desc,136char *map)137{138struct mpeg4_picparm_bsp *pic_bsp = (struct mpeg4_picparm_bsp *)map;139uint32_t t, bits = 0;140pic_bsp->width = dec->base.width;141pic_bsp->height = dec->base.height;142assert(desc->vop_time_increment_resolution > 0);143144t = desc->vop_time_increment_resolution - 1;145while (t) {146bits++;147t /= 2;148}149if (!bits)150bits = 1;151t = desc->vop_time_increment_resolution - 1;152pic_bsp->vop_time_increment_size = bits;153pic_bsp->interlaced = desc->interlaced;154pic_bsp->resync_marker_disable = desc->resync_marker_disable;155return 4;156}157158static uint32_t159nouveau_vp3_fill_picparm_vc1_bsp(struct nouveau_vp3_decoder *dec,160struct pipe_vc1_picture_desc *d,161char *map)162{163struct vc1_picparm_bsp *vc = (struct vc1_picparm_bsp *)map;164uint32_t caps = (d->slice_count << 4)&0xfff0;165vc->width = dec->base.width;166vc->height = dec->base.height;167vc->profile = dec->base.profile - PIPE_VIDEO_PROFILE_VC1_SIMPLE; // 04168vc->postprocflag = d->postprocflag;169vc->pulldown = d->pulldown;170vc->interlaced = d->interlace;171vc->tfcntrflag = d->tfcntrflag; // 08172vc->finterpflag = d->finterpflag;173vc->psf = d->psf;174vc->pad = 0;175vc->multires = d->multires; // 0c176vc->syncmarker = d->syncmarker;177vc->rangered = d->rangered;178vc->maxbframes = d->maxbframes;179vc->dquant = d->dquant; // 10180vc->panscan_flag = d->panscan_flag;181vc->refdist_flag = d->refdist_flag;182vc->quantizer = d->quantizer;183vc->extended_mv = d->extended_mv; // 14184vc->extended_dmv = d->extended_dmv;185vc->overlap = d->overlap;186vc->vstransform = d->vstransform;187return caps | 2;188}189190static uint32_t191nouveau_vp3_fill_picparm_h264_bsp(struct nouveau_vp3_decoder *dec,192struct pipe_h264_picture_desc *d,193char *map)194{195struct h264_picparm_bsp stub_h = {}, *h = &stub_h;196uint32_t caps = (d->slice_count << 4)&0xfff0;197198assert(!(d->slice_count & ~0xfff));199if (d->slice_count & 0x1000)200caps |= 1 << 20;201202assert(offsetof(struct h264_picparm_bsp, bottom_field_flag) == (0x39 + 0x24));203h->unk00 = 1;204h->pad1 = h->pad2 = 0;205h->unk = 0;206h->log2_max_frame_num_minus4 = d->pps->sps->log2_max_frame_num_minus4;207h->frame_mbs_only_flag = d->pps->sps->frame_mbs_only_flag;208h->direct_8x8_inference_flag = d->pps->sps->direct_8x8_inference_flag;209h->width_mb = mb(dec->base.width);210h->height_mb = mb(dec->base.height);211h->entropy_coding_mode_flag = d->pps->entropy_coding_mode_flag;212h->pic_order_present_flag = d->pps->bottom_field_pic_order_in_frame_present_flag;213h->pic_order_cnt_type = d->pps->sps->pic_order_cnt_type;214h->log2_max_pic_order_cnt_lsb_minus4 = d->pps->sps->log2_max_pic_order_cnt_lsb_minus4;215h->delta_pic_order_always_zero_flag = d->pps->sps->delta_pic_order_always_zero_flag;216h->num_ref_idx_l0_active_minus1 = d->num_ref_idx_l0_active_minus1;217h->num_ref_idx_l1_active_minus1 = d->num_ref_idx_l1_active_minus1;218h->weighted_pred_flag = d->pps->weighted_pred_flag;219h->weighted_bipred_idc = d->pps->weighted_bipred_idc;220h->pic_init_qp_minus26 = d->pps->pic_init_qp_minus26;221h->deblocking_filter_control_present_flag = d->pps->deblocking_filter_control_present_flag;222h->redundant_pic_cnt_present_flag = d->pps->redundant_pic_cnt_present_flag;223h->transform_8x8_mode_flag = d->pps->transform_8x8_mode_flag;224h->mb_adaptive_frame_field_flag = d->pps->sps->mb_adaptive_frame_field_flag;225h->field_pic_flag = d->field_pic_flag;226h->bottom_field_flag = d->bottom_field_flag;227memset(h->real_pad, 0, sizeof(h->real_pad));228*(struct h264_picparm_bsp *)map = *h;229return caps | 3;230}231232static inline struct strparm_bsp *strparm_bsp(struct nouveau_vp3_decoder *dec)233{234unsigned comm_seq = dec->fence_seq;235struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];236return (struct strparm_bsp *)(bsp_bo->map + 0x100);237}238239void240nouveau_vp3_bsp_begin(struct nouveau_vp3_decoder *dec)241{242struct strparm_bsp *str_bsp = strparm_bsp(dec);243244dec->bsp_ptr = (void *)str_bsp;245memset(str_bsp, 0, 0x80);246dec->bsp_ptr += 0x100;247/* Reserved for picparm_vp */248dec->bsp_ptr += 0x300;249/* Reserved for comm */250#if !NOUVEAU_VP3_DEBUG_FENCE251memset(dec->bsp_ptr, 0, 0x200);252#endif253dec->bsp_ptr += 0x200;254}255256void257nouveau_vp3_bsp_next(struct nouveau_vp3_decoder *dec, unsigned num_buffers,258const void *const *data, const unsigned *num_bytes)259{260#ifndef NDEBUG261unsigned comm_seq = dec->fence_seq;262struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];263#endif264struct strparm_bsp *str_bsp = strparm_bsp(dec);265int i;266267for (i = 0; i < num_buffers; ++i) {268#ifndef NDEBUG269assert(bsp_bo->size >= str_bsp->w0[0] + num_bytes[i]);270#endif271memcpy(dec->bsp_ptr, data[i], num_bytes[i]);272dec->bsp_ptr += num_bytes[i];273str_bsp->w0[0] += num_bytes[i];274}275}276277uint32_t278nouveau_vp3_bsp_end(struct nouveau_vp3_decoder *dec, union pipe_desc desc)279{280enum pipe_video_format codec = u_reduce_video_profile(dec->base.profile);281unsigned comm_seq = dec->fence_seq;282struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];283uint32_t endmarker, caps;284struct strparm_bsp *str_bsp = strparm_bsp(dec);285char *bsp = bsp_bo->map;286/*287* 0x000..0x100: picparm_bsp288* 0x200..0x500: picparm_vp289* 0x500..0x700: comm290* 0x700..onward: raw bitstream291*/292293switch (codec){294case PIPE_VIDEO_FORMAT_MPEG12:295endmarker = 0xb7010000;296caps = nouveau_vp3_fill_picparm_mpeg12_bsp(dec, desc.mpeg12, bsp);297break;298case PIPE_VIDEO_FORMAT_MPEG4:299endmarker = 0xb1010000;300caps = nouveau_vp3_fill_picparm_mpeg4_bsp(dec, desc.mpeg4, bsp);301break;302case PIPE_VIDEO_FORMAT_VC1: {303endmarker = 0x0a010000;304caps = nouveau_vp3_fill_picparm_vc1_bsp(dec, desc.vc1, bsp);305break;306}307case PIPE_VIDEO_FORMAT_MPEG4_AVC: {308endmarker = 0x0b010000;309caps = nouveau_vp3_fill_picparm_h264_bsp(dec, desc.h264, bsp);310break;311}312default: assert(0); return -1;313}314315caps |= 0 << 16; // reset struct comm if flag is set316caps |= 1 << 17; // enable watchdog317caps |= 0 << 18; // do not report error to VP, so it can continue decoding what we have318caps |= 0 << 19; // if enabled, use crypto crap?319320str_bsp = strparm_bsp(dec);321str_bsp->w1[0] = 0x1;322323/* Append end sequence */324*(uint32_t *)dec->bsp_ptr = endmarker;325dec->bsp_ptr += 4;326*(uint32_t *)dec->bsp_ptr = 0x00000000;327dec->bsp_ptr += 4;328*(uint32_t *)dec->bsp_ptr = endmarker;329dec->bsp_ptr += 4;330*(uint32_t *)dec->bsp_ptr = 0x00000000;331str_bsp->w0[0] += 16;332333dec->bsp_ptr = NULL;334335return caps;336}337338339