Path: blob/21.2-virgl/src/gallium/drivers/radeon/radeon_vce_40_2_2.c
4570 views
/**************************************************************************1*2* Copyright 2013 Advanced Micro Devices, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/2627#include "pipe/p_video_codec.h"28#include "radeon_vce.h"29#include "radeon_video.h"30#include "si_pipe.h"31#include "util/u_memory.h"32#include "util/u_video.h"33#include "vl/vl_video_buffer.h"3435#include <stdio.h>3637static void session(struct rvce_encoder *enc)38{39RVCE_BEGIN(0x00000001); // session cmd40RVCE_CS(enc->stream_handle);41RVCE_END();42}4344static void task_info(struct rvce_encoder *enc, uint32_t op, uint32_t dep, uint32_t fb_idx,45uint32_t ring_idx)46{47RVCE_BEGIN(0x00000002); // task info48if (op == 0x3) {49if (enc->task_info_idx) {50uint32_t offs = enc->cs.current.cdw - enc->task_info_idx + 3;51// Update offsetOfNextTaskInfo52enc->cs.current.buf[enc->task_info_idx] = offs;53}54enc->task_info_idx = enc->cs.current.cdw;55}56RVCE_CS(0xffffffff); // offsetOfNextTaskInfo57RVCE_CS(op); // taskOperation58RVCE_CS(dep); // referencePictureDependency59RVCE_CS(0x00000000); // collocateFlagDependency60RVCE_CS(fb_idx); // feedbackIndex61RVCE_CS(ring_idx); // videoBitstreamRingIndex62RVCE_END();63}6465static void feedback(struct rvce_encoder *enc)66{67RVCE_BEGIN(0x05000005); // feedback buffer68RVCE_WRITE(enc->fb->res->buf, enc->fb->res->domains, 0x0); // feedbackRingAddressHi/Lo69RVCE_CS(0x00000001); // feedbackRingSize70RVCE_END();71}7273static void create(struct rvce_encoder *enc)74{75enc->task_info(enc, 0x00000000, 0, 0, 0);7677RVCE_BEGIN(0x01000001); // create cmd78RVCE_CS(0x00000000); // encUseCircularBuffer79RVCE_CS(u_get_h264_profile_idc(enc->base.profile)); // encProfile80RVCE_CS(enc->base.level); // encLevel81RVCE_CS(0x00000000); // encPicStructRestriction82RVCE_CS(enc->base.width); // encImageWidth83RVCE_CS(enc->base.height); // encImageHeight84RVCE_CS(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe); // encRefPicLumaPitch85RVCE_CS(enc->chroma->u.legacy.level[0].nblk_x * enc->chroma->bpe); // encRefPicChromaPitch86RVCE_CS(align(enc->luma->u.legacy.level[0].nblk_y, 16) / 8); // encRefYHeightInQw87RVCE_CS(0x00000000); // encRefPic(Addr|Array)Mode, encPicStructRestriction, disableRDO88RVCE_END();89}9091static void rate_control(struct rvce_encoder *enc)92{93RVCE_BEGIN(0x04000005); // rate control94RVCE_CS(enc->pic.rate_ctrl.rate_ctrl_method); // encRateControlMethod95RVCE_CS(enc->pic.rate_ctrl.target_bitrate); // encRateControlTargetBitRate96RVCE_CS(enc->pic.rate_ctrl.peak_bitrate); // encRateControlPeakBitRate97RVCE_CS(enc->pic.rate_ctrl.frame_rate_num); // encRateControlFrameRateNum98RVCE_CS(0x00000000); // encGOPSize99RVCE_CS(enc->pic.quant_i_frames); // encQP_I100RVCE_CS(enc->pic.quant_p_frames); // encQP_P101RVCE_CS(enc->pic.quant_b_frames); // encQP_B102RVCE_CS(enc->pic.rate_ctrl.vbv_buffer_size); // encVBVBufferSize103RVCE_CS(enc->pic.rate_ctrl.frame_rate_den); // encRateControlFrameRateDen104RVCE_CS(0x00000000); // encVBVBufferLevel105RVCE_CS(0x00000000); // encMaxAUSize106RVCE_CS(0x00000000); // encQPInitialMode107RVCE_CS(enc->pic.rate_ctrl.target_bits_picture); // encTargetBitsPerPicture108RVCE_CS(enc->pic.rate_ctrl.peak_bits_picture_integer); // encPeakBitsPerPictureInteger109RVCE_CS(enc->pic.rate_ctrl.peak_bits_picture_fraction); // encPeakBitsPerPictureFractional110RVCE_CS(0x00000000); // encMinQP111RVCE_CS(0x00000033); // encMaxQP112RVCE_CS(0x00000000); // encSkipFrameEnable113RVCE_CS(0x00000000); // encFillerDataEnable114RVCE_CS(0x00000000); // encEnforceHRD115RVCE_CS(0x00000000); // encBPicsDeltaQP116RVCE_CS(0x00000000); // encReferenceBPicsDeltaQP117RVCE_CS(0x00000000); // encRateControlReInitDisable118RVCE_END();119}120121static void config_extension(struct rvce_encoder *enc)122{123RVCE_BEGIN(0x04000001); // config extension124RVCE_CS(0x00000003); // encEnablePerfLogging125RVCE_END();126}127128static void pic_control(struct rvce_encoder *enc)129{130unsigned encNumMBsPerSlice;131132encNumMBsPerSlice = align(enc->base.width, 16) / 16;133encNumMBsPerSlice *= align(enc->base.height, 16) / 16;134135RVCE_BEGIN(0x04000002); // pic control136RVCE_CS(0x00000000); // encUseConstrainedIntraPred137RVCE_CS(0x00000000); // encCABACEnable138RVCE_CS(0x00000000); // encCABACIDC139RVCE_CS(0x00000000); // encLoopFilterDisable140RVCE_CS(0x00000000); // encLFBetaOffset141RVCE_CS(0x00000000); // encLFAlphaC0Offset142RVCE_CS(0x00000000); // encCropLeftOffset143RVCE_CS((align(enc->base.width, 16) - enc->base.width) >> 1); // encCropRightOffset144RVCE_CS(0x00000000); // encCropTopOffset145RVCE_CS((align(enc->base.height, 16) - enc->base.height) >> 1); // encCropBottomOffset146RVCE_CS(encNumMBsPerSlice); // encNumMBsPerSlice147RVCE_CS(0x00000000); // encIntraRefreshNumMBsPerSlot148RVCE_CS(0x00000000); // encForceIntraRefresh149RVCE_CS(0x00000000); // encForceIMBPeriod150RVCE_CS(0x00000000); // encPicOrderCntType151RVCE_CS(0x00000000); // log2_max_pic_order_cnt_lsb_minus4152RVCE_CS(0x00000000); // encSPSID153RVCE_CS(0x00000000); // encPPSID154RVCE_CS(0x00000040); // encConstraintSetFlags155RVCE_CS(MAX2(enc->base.max_references, 1) - 1); // encBPicPattern156RVCE_CS(0x00000000); // weightPredModeBPicture157RVCE_CS(MIN2(enc->base.max_references, 2)); // encNumberOfReferenceFrames158RVCE_CS(enc->base.max_references + 1); // encMaxNumRefFrames159RVCE_CS(0x00000001); // encNumDefaultActiveRefL0160RVCE_CS(0x00000001); // encNumDefaultActiveRefL1161RVCE_CS(0x00000000); // encSliceMode162RVCE_CS(0x00000000); // encMaxSliceSize163RVCE_END();164}165166static void motion_estimation(struct rvce_encoder *enc)167{168RVCE_BEGIN(0x04000007); // motion estimation169RVCE_CS(0x00000001); // encIMEDecimationSearch170RVCE_CS(0x00000001); // motionEstHalfPixel171RVCE_CS(0x00000000); // motionEstQuarterPixel172RVCE_CS(0x00000000); // disableFavorPMVPoint173RVCE_CS(0x00000000); // forceZeroPointCenter174RVCE_CS(0x00000000); // LSMVert175RVCE_CS(0x00000010); // encSearchRangeX176RVCE_CS(0x00000010); // encSearchRangeY177RVCE_CS(0x00000010); // encSearch1RangeX178RVCE_CS(0x00000010); // encSearch1RangeY179RVCE_CS(0x00000000); // disable16x16Frame1180RVCE_CS(0x00000000); // disableSATD181RVCE_CS(0x00000000); // enableAMD182RVCE_CS(0x000000fe); // encDisableSubMode183RVCE_CS(0x00000000); // encIMESkipX184RVCE_CS(0x00000000); // encIMESkipY185RVCE_CS(0x00000000); // encEnImeOverwDisSubm186RVCE_CS(0x00000000); // encImeOverwDisSubmNo187RVCE_CS(0x00000001); // encIME2SearchRangeX188RVCE_CS(0x00000001); // encIME2SearchRangeY189RVCE_CS(0x00000000); // parallelModeSpeedupEnable190RVCE_CS(0x00000000); // fme0_encDisableSubMode191RVCE_CS(0x00000000); // fme1_encDisableSubMode192RVCE_CS(0x00000000); // imeSWSpeedupEnable193RVCE_END();194}195196static void rdo(struct rvce_encoder *enc)197{198RVCE_BEGIN(0x04000008); // rdo199RVCE_CS(0x00000000); // encDisableTbePredIFrame200RVCE_CS(0x00000000); // encDisableTbePredPFrame201RVCE_CS(0x00000000); // useFmeInterpolY202RVCE_CS(0x00000000); // useFmeInterpolUV203RVCE_CS(0x00000000); // useFmeIntrapolY204RVCE_CS(0x00000000); // useFmeIntrapolUV205RVCE_CS(0x00000000); // useFmeInterpolY_1206RVCE_CS(0x00000000); // useFmeInterpolUV_1207RVCE_CS(0x00000000); // useFmeIntrapolY_1208RVCE_CS(0x00000000); // useFmeIntrapolUV_1209RVCE_CS(0x00000000); // enc16x16CostAdj210RVCE_CS(0x00000000); // encSkipCostAdj211RVCE_CS(0x00000000); // encForce16x16skip212RVCE_CS(0x00000000); // encDisableThresholdCalcA213RVCE_CS(0x00000000); // encLumaCoeffCost214RVCE_CS(0x00000000); // encLumaMBCoeffCost215RVCE_CS(0x00000000); // encChromaCoeffCost216RVCE_END();217}218219static void vui(struct rvce_encoder *enc)220{221int i;222223if (!enc->pic.rate_ctrl.frame_rate_num)224return;225226RVCE_BEGIN(0x04000009); // vui227RVCE_CS(0x00000000); // aspectRatioInfoPresentFlag228RVCE_CS(0x00000000); // aspectRatioInfo.aspectRatioIdc229RVCE_CS(0x00000000); // aspectRatioInfo.sarWidth230RVCE_CS(0x00000000); // aspectRatioInfo.sarHeight231RVCE_CS(0x00000000); // overscanInfoPresentFlag232RVCE_CS(0x00000000); // overScanInfo.overscanAppropFlag233RVCE_CS(0x00000000); // videoSignalTypePresentFlag234RVCE_CS(0x00000005); // videoSignalTypeInfo.videoFormat235RVCE_CS(0x00000000); // videoSignalTypeInfo.videoFullRangeFlag236RVCE_CS(0x00000000); // videoSignalTypeInfo.colorDescriptionPresentFlag237RVCE_CS(0x00000002); // videoSignalTypeInfo.colorPrim238RVCE_CS(0x00000002); // videoSignalTypeInfo.transferChar239RVCE_CS(0x00000002); // videoSignalTypeInfo.matrixCoef240RVCE_CS(0x00000000); // chromaLocInfoPresentFlag241RVCE_CS(0x00000000); // chromaLocInfo.chromaLocTop242RVCE_CS(0x00000000); // chromaLocInfo.chromaLocBottom243RVCE_CS(0x00000001); // timingInfoPresentFlag244RVCE_CS(enc->pic.rate_ctrl.frame_rate_den); // timingInfo.numUnitsInTick245RVCE_CS(enc->pic.rate_ctrl.frame_rate_num * 2); // timingInfo.timeScale;246RVCE_CS(0x00000001); // timingInfo.fixedFrameRateFlag247RVCE_CS(0x00000000); // nalHRDParametersPresentFlag248RVCE_CS(0x00000000); // hrdParam.cpbCntMinus1249RVCE_CS(0x00000004); // hrdParam.bitRateScale250RVCE_CS(0x00000006); // hrdParam.cpbSizeScale251for (i = 0; i < 32; i++) {252RVCE_CS(0x00000000); // hrdParam.bitRateValueMinus253RVCE_CS(0x00000000); // hrdParam.cpbSizeValueMinus254RVCE_CS(0x00000000); // hrdParam.cbrFlag255}256RVCE_CS(0x00000017); // hrdParam.initialCpbRemovalDelayLengthMinus1257RVCE_CS(0x00000017); // hrdParam.cpbRemovalDelayLengthMinus1258RVCE_CS(0x00000017); // hrdParam.dpbOutputDelayLengthMinus1259RVCE_CS(0x00000018); // hrdParam.timeOffsetLength260RVCE_CS(0x00000000); // lowDelayHRDFlag261RVCE_CS(0x00000000); // picStructPresentFlag262RVCE_CS(0x00000000); // bitstreamRestrictionPresentFlag263RVCE_CS(0x00000001); // bitstreamRestrictions.motionVectorsOverPicBoundariesFlag264RVCE_CS(0x00000002); // bitstreamRestrictions.maxBytesPerPicDenom265RVCE_CS(0x00000001); // bitstreamRestrictions.maxBitsPerMbDenom266RVCE_CS(0x00000010); // bitstreamRestrictions.log2MaxMvLengthHori267RVCE_CS(0x00000010); // bitstreamRestrictions.log2MaxMvLengthVert268RVCE_CS(0x00000003); // bitstreamRestrictions.numReorderFrames269RVCE_CS(0x00000003); // bitstreamRestrictions.maxDecFrameBuffering270RVCE_END();271}272273static void config(struct rvce_encoder *enc)274{275enc->task_info(enc, 0x00000002, 0, 0xffffffff, 0);276enc->rate_control(enc);277enc->config_extension(enc);278enc->motion_estimation(enc);279enc->rdo(enc);280if (enc->use_vui)281enc->vui(enc);282enc->pic_control(enc);283}284285static void encode(struct rvce_encoder *enc)286{287signed luma_offset, chroma_offset;288int i;289290enc->task_info(enc, 0x00000003, 0, 0, 0);291292RVCE_BEGIN(0x05000001); // context buffer293RVCE_READWRITE(enc->cpb.res->buf, enc->cpb.res->domains, 0x0); // encodeContextAddressHi/Lo294RVCE_END();295296RVCE_BEGIN(0x05000004); // video bitstream buffer297RVCE_WRITE(enc->bs_handle, RADEON_DOMAIN_GTT, 0x0); // videoBitstreamRingAddressHi/Lo298RVCE_CS(enc->bs_size); // videoBitstreamRingSize299RVCE_END();300301RVCE_BEGIN(0x03000001); // encode302RVCE_CS(0x00000000); // insertHeaders303RVCE_CS(0x00000000); // pictureStructure304RVCE_CS(enc->bs_size); // allowedMaxBitstreamSize305RVCE_CS(0x00000000); // forceRefreshMap306RVCE_CS(0x00000000); // insertAUD307RVCE_CS(0x00000000); // endOfSequence308RVCE_CS(0x00000000); // endOfStream309RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM,310(uint64_t)enc->luma->u.legacy.level[0].offset_256B * 256); // inputPictureLumaAddressHi/Lo311RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM,312(uint64_t)enc->chroma->u.legacy.level[0].offset_256B * 256); // inputPictureChromaAddressHi/Lo313RVCE_CS(align(enc->luma->u.legacy.level[0].nblk_y, 16)); // encInputFrameYPitch314RVCE_CS(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe); // encInputPicLumaPitch315RVCE_CS(enc->chroma->u.legacy.level[0].nblk_x * enc->chroma->bpe); // encInputPicChromaPitch316RVCE_CS(0x00000000); // encInputPic(Addr|Array)Mode317RVCE_CS(0x00000000); // encInputPicTileConfig318RVCE_CS(enc->pic.picture_type); // encPicType319RVCE_CS(enc->pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR); // encIdrFlag320RVCE_CS(0x00000000); // encIdrPicId321RVCE_CS(0x00000000); // encMGSKeyPic322RVCE_CS(!enc->pic.not_referenced); // encReferenceFlag323RVCE_CS(0x00000000); // encTemporalLayerIndex324RVCE_CS(0x00000000); // num_ref_idx_active_override_flag325RVCE_CS(0x00000000); // num_ref_idx_l0_active_minus1326RVCE_CS(0x00000000); // num_ref_idx_l1_active_minus1327328i = enc->pic.frame_num - enc->pic.ref_idx_l0;329if (i > 1 && enc->pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_P) {330RVCE_CS(0x00000001); // encRefListModificationOp331RVCE_CS(i - 1); // encRefListModificationNum332} else {333RVCE_CS(0x00000000); // encRefListModificationOp334RVCE_CS(0x00000000); // encRefListModificationNum335}336337for (i = 0; i < 3; ++i) {338RVCE_CS(0x00000000); // encRefListModificationOp339RVCE_CS(0x00000000); // encRefListModificationNum340}341for (i = 0; i < 4; ++i) {342RVCE_CS(0x00000000); // encDecodedPictureMarkingOp343RVCE_CS(0x00000000); // encDecodedPictureMarkingNum344RVCE_CS(0x00000000); // encDecodedPictureMarkingIdx345RVCE_CS(0x00000000); // encDecodedRefBasePictureMarkingOp346RVCE_CS(0x00000000); // encDecodedRefBasePictureMarkingNum347}348349// encReferencePictureL0[0]350RVCE_CS(0x00000000); // pictureStructure351if (enc->pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_P ||352enc->pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_B) {353struct rvce_cpb_slot *l0 = si_l0_slot(enc);354si_vce_frame_offset(enc, l0, &luma_offset, &chroma_offset);355RVCE_CS(l0->picture_type); // encPicType356RVCE_CS(l0->frame_num); // frameNumber357RVCE_CS(l0->pic_order_cnt); // pictureOrderCount358RVCE_CS(luma_offset); // lumaOffset359RVCE_CS(chroma_offset); // chromaOffset360} else {361RVCE_CS(0x00000000); // encPicType362RVCE_CS(0x00000000); // frameNumber363RVCE_CS(0x00000000); // pictureOrderCount364RVCE_CS(0xffffffff); // lumaOffset365RVCE_CS(0xffffffff); // chromaOffset366}367368// encReferencePictureL0[1]369RVCE_CS(0x00000000); // pictureStructure370RVCE_CS(0x00000000); // encPicType371RVCE_CS(0x00000000); // frameNumber372RVCE_CS(0x00000000); // pictureOrderCount373RVCE_CS(0xffffffff); // lumaOffset374RVCE_CS(0xffffffff); // chromaOffset375376// encReferencePictureL1[0]377RVCE_CS(0x00000000); // pictureStructure378if (enc->pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_B) {379struct rvce_cpb_slot *l1 = si_l1_slot(enc);380si_vce_frame_offset(enc, l1, &luma_offset, &chroma_offset);381RVCE_CS(l1->picture_type); // encPicType382RVCE_CS(l1->frame_num); // frameNumber383RVCE_CS(l1->pic_order_cnt); // pictureOrderCount384RVCE_CS(luma_offset); // lumaOffset385RVCE_CS(chroma_offset); // chromaOffset386} else {387RVCE_CS(0x00000000); // encPicType388RVCE_CS(0x00000000); // frameNumber389RVCE_CS(0x00000000); // pictureOrderCount390RVCE_CS(0xffffffff); // lumaOffset391RVCE_CS(0xffffffff); // chromaOffset392}393394si_vce_frame_offset(enc, si_current_slot(enc), &luma_offset, &chroma_offset);395RVCE_CS(luma_offset); // encReconstructedLumaOffset396RVCE_CS(chroma_offset); // encReconstructedChromaOffset397RVCE_CS(0x00000000); // encColocBufferOffset398RVCE_CS(0x00000000); // encReconstructedRefBasePictureLumaOffset399RVCE_CS(0x00000000); // encReconstructedRefBasePictureChromaOffset400RVCE_CS(0x00000000); // encReferenceRefBasePictureLumaOffset401RVCE_CS(0x00000000); // encReferenceRefBasePictureChromaOffset402RVCE_CS(0x00000000); // pictureCount403RVCE_CS(enc->pic.frame_num); // frameNumber404RVCE_CS(enc->pic.pic_order_cnt); // pictureOrderCount405RVCE_CS(0x00000000); // numIPicRemainInRCGOP406RVCE_CS(0x00000000); // numPPicRemainInRCGOP407RVCE_CS(0x00000000); // numBPicRemainInRCGOP408RVCE_CS(0x00000000); // numIRPicRemainInRCGOP409RVCE_CS(0x00000000); // enableIntraRefresh410RVCE_END();411}412413static void destroy(struct rvce_encoder *enc)414{415enc->task_info(enc, 0x00000001, 0, 0, 0);416417feedback(enc);418419RVCE_BEGIN(0x02000001); // destroy420RVCE_END();421}422423void si_vce_40_2_2_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic)424{425}426427void si_vce_40_2_2_init(struct rvce_encoder *enc)428{429enc->session = session;430enc->task_info = task_info;431enc->create = create;432enc->feedback = feedback;433enc->rate_control = rate_control;434enc->config_extension = config_extension;435enc->pic_control = pic_control;436enc->motion_estimation = motion_estimation;437enc->rdo = rdo;438enc->vui = vui;439enc->config = config;440enc->encode = encode;441enc->destroy = destroy;442enc->si_get_pic_param = si_vce_40_2_2_get_param;443}444445446