Path: blob/21.2-virgl/src/gallium/drivers/nouveau/nouveau_vp3_video.h
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.h>2324#include "pipe/p_defines.h"25#include "vl/vl_video_buffer.h"26#include "util/u_video.h"2728struct nouveau_vp3_video_buffer {29struct pipe_video_buffer base;30unsigned num_planes, valid_ref;31struct pipe_resource *resources[VL_NUM_COMPONENTS];32struct pipe_sampler_view *sampler_view_planes[VL_NUM_COMPONENTS];33struct pipe_sampler_view *sampler_view_components[VL_NUM_COMPONENTS];34struct pipe_surface *surfaces[VL_NUM_COMPONENTS * 2];35};3637#define SLICE_SIZE 0x20038#define VP_OFFSET 0x20039#define COMM_OFFSET 0x5004041#define NOUVEAU_VP3_BSP_RESERVED_SIZE 0x7004243#define NOUVEAU_VP3_DEBUG_FENCE 04445#if NOUVEAU_VP3_DEBUG_FENCE46# define NOUVEAU_VP3_VIDEO_QDEPTH 147#else48# define NOUVEAU_VP3_VIDEO_QDEPTH 249#endif5051#define SUBC_BSP(m) dec->bsp_idx, (m)52#define SUBC_VP(m) dec->vp_idx, (m)53#define SUBC_PPP(m) dec->ppp_idx, (m)5455union pipe_desc {56struct pipe_picture_desc *base;57struct pipe_mpeg12_picture_desc *mpeg12;58struct pipe_mpeg4_picture_desc *mpeg4;59struct pipe_vc1_picture_desc *vc1;60struct pipe_h264_picture_desc *h264;61};6263struct nouveau_vp3_decoder {64struct pipe_video_codec base;65struct nouveau_client *client;66struct nouveau_object *channel[3], *bsp, *vp, *ppp;67struct nouveau_pushbuf *pushbuf[3];6869#if NOUVEAU_VP3_DEBUG_FENCE70/* dump fence and comm, as needed.. */71unsigned *fence_map;72struct comm *comm;7374struct nouveau_bo *fence_bo;75#endif7677struct nouveau_bo *fw_bo, *bitplane_bo;7879// array size max_references + 2, contains unpostprocessed images80// added at the end of ref_bo is a tmp array81// tmp is an array for h264, with each member being used for a ref frame or current82// target.. size = (((mb(w)*((mb(h)+1)&~1))+3)>>2)<<8 * (max_references+1)83// for other codecs, it simply seems that size = w*h is enough84// unsure what it's supposed to contain..85struct nouveau_bo *ref_bo;8687struct nouveau_bo *inter_bo[2];8889struct nouveau_bo *bsp_bo[NOUVEAU_VP3_VIDEO_QDEPTH];9091// bo's used by each cycle:9293// bsp_bo: contains raw bitstream data and parameters for BSP and VP.94// inter_bo: contains data shared between BSP and VP95// ref_bo: reference image data, used by PPP and VP96// bitplane_bo: contain bitplane data (similar to ref_bo), used by BSP only97// fw_bo: used by VP only.9899// Needed amount of copies in optimal case:100// 2 copies of inter_bo, VP would process the last inter_bo, while BSP is101// writing out a new set.102// NOUVEAU_VP3_VIDEO_QDEPTH copies of bsp_bo. We don't want to block the103// pipeline ever, and give shaders a chance to run as well.104105struct {106struct nouveau_vp3_video_buffer *vidbuf;107unsigned last_used;108unsigned field_pic_flag : 1;109unsigned decoded_top : 1;110unsigned decoded_bottom : 1;111unsigned decoded_first : 1;112} refs[17];113unsigned fence_seq, fw_sizes, last_frame_num, tmp_stride, ref_stride;114115unsigned bsp_idx, vp_idx, ppp_idx;116117/* End of the bsp bo where new data should be appended between one begin/end118* frame.119*/120char *bsp_ptr;121};122123struct comm {124uint32_t bsp_cur_index; // 000125uint32_t byte_ofs; // 004126uint32_t status[0x10]; // 008127uint32_t pos[0x10]; // 048128uint8_t pad[0x100 - 0x88]; // 0a0 bool comm_encrypted129130uint32_t pvp_cur_index; // 100131uint32_t acked_byte_ofs; // 104132uint32_t status_vp[0x10]; // 108133uint16_t mb_y[0x10]; //148134uint32_t pvp_stage; // 168 0xeeXX135uint16_t parse_endpos_index; // 16c136uint16_t irq_index; // 16e137uint8_t irq_470[0x10]; // 170138uint32_t irq_pos[0x10]; // 180139uint32_t parse_endpos[0x10]; // 1c0140};141142static inline uint32_t nouveau_vp3_video_align(uint32_t h)143{144return ((h+0x3f)&~0x3f);145};146147static inline uint32_t mb(uint32_t coord)148{149return (coord + 0xf)>>4;150}151152static inline uint32_t mb_half(uint32_t coord)153{154return (coord + 0x1f)>>5;155}156157static inline uint64_t158nouveau_vp3_video_addr(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video_buffer *target)159{160uint64_t ret;161if (target)162ret = dec->ref_stride * target->valid_ref;163else164ret = dec->ref_stride * (dec->base.max_references+1);165return dec->ref_bo->offset + ret;166}167168static inline void169nouveau_vp3_ycbcr_offsets(struct nouveau_vp3_decoder *dec, uint32_t *y2,170uint32_t *cbcr, uint32_t *cbcr2)171{172uint32_t w = mb(dec->base.width), size;173*y2 = mb_half(dec->base.height)*w;174*cbcr = *y2 * 2;175*cbcr2 = *cbcr + w * (nouveau_vp3_video_align(dec->base.height)>>6);176177/* The check here should never fail because it means a bug178* in the code rather than a bug in hardware..179*/180size = (2 * (*cbcr2 - *cbcr) + *cbcr) << 8;181if (size > dec->ref_stride) {182debug_printf("Overshot ref_stride (%u) with size %u and ofs (%u,%u,%u)\n",183dec->ref_stride, size, *y2<<8, *cbcr<<8, *cbcr2<<8);184*y2 = *cbcr = *cbcr2 = 0;185assert(size <= dec->ref_stride);186}187}188189static inline void190nouveau_vp3_inter_sizes(struct nouveau_vp3_decoder *dec, uint32_t slice_count,191uint32_t *slice_size, uint32_t *bucket_size,192uint32_t *ring_size)193{194*slice_size = (SLICE_SIZE * slice_count)>>8;195if (u_reduce_video_profile(dec->base.profile) == PIPE_VIDEO_FORMAT_MPEG12)196*bucket_size = 0;197else198*bucket_size = mb(dec->base.width) * 3;199*ring_size = (dec->inter_bo[0]->size >> 8) - *bucket_size - *slice_size;200}201202struct pipe_video_buffer *203nouveau_vp3_video_buffer_create(struct pipe_context *pipe,204const struct pipe_video_buffer *templat,205int flags);206207void208nouveau_vp3_decoder_init_common(struct pipe_video_codec *decoder);209210int211nouveau_vp3_load_firmware(struct nouveau_vp3_decoder *dec,212enum pipe_video_profile profile,213unsigned chipset);214215void216nouveau_vp3_bsp_begin(struct nouveau_vp3_decoder *dec);217218void219nouveau_vp3_bsp_next(struct nouveau_vp3_decoder *dec, unsigned num_buffers,220const void *const *data, const unsigned *num_bytes);221222uint32_t223nouveau_vp3_bsp_end(struct nouveau_vp3_decoder *dec, union pipe_desc desc);224225void226nouveau_vp3_vp_caps(struct nouveau_vp3_decoder *dec, union pipe_desc desc,227struct nouveau_vp3_video_buffer *target, unsigned comm_seq,228unsigned *caps, unsigned *is_ref,229struct nouveau_vp3_video_buffer *refs[16]);230231int232nouveau_vp3_screen_get_video_param(struct pipe_screen *pscreen,233enum pipe_video_profile profile,234enum pipe_video_entrypoint entrypoint,235enum pipe_video_cap param);236237bool238nouveau_vp3_screen_video_supported(struct pipe_screen *screen,239enum pipe_format format,240enum pipe_video_profile profile,241enum pipe_video_entrypoint entrypoint);242243244