Home | History | Annotate | Download | only in radeon
      1 /**************************************************************************
      2  *
      3  * Copyright 2013 Advanced Micro Devices, Inc.
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     21  * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
     22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27 
     28 /*
     29  * Authors:
     30  *      Christian Knig <christian.koenig (at) amd.com>
     31  *
     32  */
     33 
     34 #include <stdio.h>
     35 
     36 #include "pipe/p_video_codec.h"
     37 
     38 #include "util/u_video.h"
     39 #include "util/u_memory.h"
     40 
     41 #include "vl/vl_video_buffer.h"
     42 
     43 #include "r600_pipe_common.h"
     44 #include "radeon_video.h"
     45 #include "radeon_vce.h"
     46 
     47 static const unsigned profiles[7] = { 66, 77, 88, 100, 110, 122, 244 };
     48 
     49 static void session(struct rvce_encoder *enc)
     50 {
     51 	RVCE_BEGIN(0x00000001); // session cmd
     52 	RVCE_CS(enc->stream_handle);
     53 	RVCE_END();
     54 }
     55 
     56 static void task_info(struct rvce_encoder *enc, uint32_t op,
     57 		      uint32_t dep, uint32_t fb_idx, uint32_t ring_idx)
     58 {
     59 	RVCE_BEGIN(0x00000002); // task info
     60 	if (op == 0x3) {
     61 		if (enc->task_info_idx) {
     62 			uint32_t offs = enc->cs->current.cdw - enc->task_info_idx + 3;
     63 			// Update offsetOfNextTaskInfo
     64 			enc->cs->current.buf[enc->task_info_idx] = offs;
     65 		}
     66 		enc->task_info_idx = enc->cs->current.cdw;
     67 	}
     68 	RVCE_CS(0xffffffff); // offsetOfNextTaskInfo
     69 	RVCE_CS(op); // taskOperation
     70 	RVCE_CS(dep); // referencePictureDependency
     71 	RVCE_CS(0x00000000); // collocateFlagDependency
     72 	RVCE_CS(fb_idx); // feedbackIndex
     73 	RVCE_CS(ring_idx); // videoBitstreamRingIndex
     74 	RVCE_END();
     75 }
     76 
     77 static void feedback(struct rvce_encoder *enc)
     78 {
     79 	RVCE_BEGIN(0x05000005); // feedback buffer
     80 	RVCE_WRITE(enc->fb->res->buf, enc->fb->res->domains, 0x0); // feedbackRingAddressHi/Lo
     81 	RVCE_CS(0x00000001); // feedbackRingSize
     82 	RVCE_END();
     83 }
     84 
     85 static void create(struct rvce_encoder *enc)
     86 {
     87 	enc->task_info(enc, 0x00000000, 0, 0, 0);
     88 
     89 	RVCE_BEGIN(0x01000001); // create cmd
     90 	RVCE_CS(0x00000000); // encUseCircularBuffer
     91 	RVCE_CS(profiles[enc->base.profile -
     92 		PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE]); // encProfile
     93 	RVCE_CS(enc->base.level); // encLevel
     94 	RVCE_CS(0x00000000); // encPicStructRestriction
     95 	RVCE_CS(enc->base.width); // encImageWidth
     96 	RVCE_CS(enc->base.height); // encImageHeight
     97 	RVCE_CS(enc->luma->level[0].nblk_x * enc->luma->bpe); // encRefPicLumaPitch
     98 	RVCE_CS(enc->chroma->level[0].nblk_x * enc->chroma->bpe); // encRefPicChromaPitch
     99 	RVCE_CS(align(enc->luma->level[0].nblk_y, 16) / 8); // encRefYHeightInQw
    100 	RVCE_CS(0x00000000); // encRefPic(Addr|Array)Mode, encPicStructRestriction, disableRDO
    101 	RVCE_END();
    102 }
    103 
    104 static void rate_control(struct rvce_encoder *enc)
    105 {
    106 	RVCE_BEGIN(0x04000005); // rate control
    107 	RVCE_CS(enc->pic.rate_ctrl.rate_ctrl_method); // encRateControlMethod
    108 	RVCE_CS(enc->pic.rate_ctrl.target_bitrate); // encRateControlTargetBitRate
    109 	RVCE_CS(enc->pic.rate_ctrl.peak_bitrate); // encRateControlPeakBitRate
    110 	RVCE_CS(enc->pic.rate_ctrl.frame_rate_num); // encRateControlFrameRateNum
    111 	RVCE_CS(0x00000000); // encGOPSize
    112 	RVCE_CS(enc->pic.quant_i_frames); // encQP_I
    113 	RVCE_CS(enc->pic.quant_p_frames); // encQP_P
    114 	RVCE_CS(enc->pic.quant_b_frames); // encQP_B
    115 	RVCE_CS(enc->pic.rate_ctrl.vbv_buffer_size); // encVBVBufferSize
    116 	RVCE_CS(enc->pic.rate_ctrl.frame_rate_den); // encRateControlFrameRateDen
    117 	RVCE_CS(0x00000000); // encVBVBufferLevel
    118 	RVCE_CS(0x00000000); // encMaxAUSize
    119 	RVCE_CS(0x00000000); // encQPInitialMode
    120 	RVCE_CS(enc->pic.rate_ctrl.target_bits_picture); // encTargetBitsPerPicture
    121 	RVCE_CS(enc->pic.rate_ctrl.peak_bits_picture_integer); // encPeakBitsPerPictureInteger
    122 	RVCE_CS(enc->pic.rate_ctrl.peak_bits_picture_fraction); // encPeakBitsPerPictureFractional
    123 	RVCE_CS(0x00000000); // encMinQP
    124 	RVCE_CS(0x00000033); // encMaxQP
    125 	RVCE_CS(0x00000000); // encSkipFrameEnable
    126 	RVCE_CS(0x00000000); // encFillerDataEnable
    127 	RVCE_CS(0x00000000); // encEnforceHRD
    128 	RVCE_CS(0x00000000); // encBPicsDeltaQP
    129 	RVCE_CS(0x00000000); // encReferenceBPicsDeltaQP
    130 	RVCE_CS(0x00000000); // encRateControlReInitDisable
    131 	RVCE_END();
    132 }
    133 
    134 static void config_extension(struct rvce_encoder *enc)
    135 {
    136 	RVCE_BEGIN(0x04000001); // config extension
    137 	RVCE_CS(0x00000003); // encEnablePerfLogging
    138 	RVCE_END();
    139 }
    140 
    141 static void pic_control(struct rvce_encoder *enc)
    142 {
    143 	unsigned encNumMBsPerSlice;
    144 
    145 	encNumMBsPerSlice = align(enc->base.width, 16) / 16;
    146 	encNumMBsPerSlice *= align(enc->base.height, 16) / 16;
    147 
    148 	RVCE_BEGIN(0x04000002); // pic control
    149 	RVCE_CS(0x00000000); // encUseConstrainedIntraPred
    150 	RVCE_CS(0x00000000); // encCABACEnable
    151 	RVCE_CS(0x00000000); // encCABACIDC
    152 	RVCE_CS(0x00000000); // encLoopFilterDisable
    153 	RVCE_CS(0x00000000); // encLFBetaOffset
    154 	RVCE_CS(0x00000000); // encLFAlphaC0Offset
    155 	RVCE_CS(0x00000000); // encCropLeftOffset
    156 	RVCE_CS((align(enc->base.width, 16) - enc->base.width) >> 1); // encCropRightOffset
    157 	RVCE_CS(0x00000000); // encCropTopOffset
    158 	RVCE_CS((align(enc->base.height, 16) - enc->base.height) >> 1); // encCropBottomOffset
    159 	RVCE_CS(encNumMBsPerSlice); // encNumMBsPerSlice
    160 	RVCE_CS(0x00000000); // encIntraRefreshNumMBsPerSlot
    161 	RVCE_CS(0x00000000); // encForceIntraRefresh
    162 	RVCE_CS(0x00000000); // encForceIMBPeriod
    163 	RVCE_CS(0x00000000); // encPicOrderCntType
    164 	RVCE_CS(0x00000000); // log2_max_pic_order_cnt_lsb_minus4
    165 	RVCE_CS(0x00000000); // encSPSID
    166 	RVCE_CS(0x00000000); // encPPSID
    167 	RVCE_CS(0x00000040); // encConstraintSetFlags
    168 	RVCE_CS(MAX2(enc->base.max_references, 1) - 1); // encBPicPattern
    169 	RVCE_CS(0x00000000); // weightPredModeBPicture
    170 	RVCE_CS(MIN2(enc->base.max_references, 2)); // encNumberOfReferenceFrames
    171 	RVCE_CS(enc->base.max_references + 1); // encMaxNumRefFrames
    172 	RVCE_CS(0x00000001); // encNumDefaultActiveRefL0
    173 	RVCE_CS(0x00000001); // encNumDefaultActiveRefL1
    174 	RVCE_CS(0x00000000); // encSliceMode
    175 	RVCE_CS(0x00000000); // encMaxSliceSize
    176 	RVCE_END();
    177 }
    178 
    179 static void motion_estimation(struct rvce_encoder *enc)
    180 {
    181 	RVCE_BEGIN(0x04000007); // motion estimation
    182 	RVCE_CS(0x00000001); // encIMEDecimationSearch
    183 	RVCE_CS(0x00000001); // motionEstHalfPixel
    184 	RVCE_CS(0x00000000); // motionEstQuarterPixel
    185 	RVCE_CS(0x00000000); // disableFavorPMVPoint
    186 	RVCE_CS(0x00000000); // forceZeroPointCenter
    187 	RVCE_CS(0x00000000); // LSMVert
    188 	RVCE_CS(0x00000010); // encSearchRangeX
    189 	RVCE_CS(0x00000010); // encSearchRangeY
    190 	RVCE_CS(0x00000010); // encSearch1RangeX
    191 	RVCE_CS(0x00000010); // encSearch1RangeY
    192 	RVCE_CS(0x00000000); // disable16x16Frame1
    193 	RVCE_CS(0x00000000); // disableSATD
    194 	RVCE_CS(0x00000000); // enableAMD
    195 	RVCE_CS(0x000000fe); // encDisableSubMode
    196 	RVCE_CS(0x00000000); // encIMESkipX
    197 	RVCE_CS(0x00000000); // encIMESkipY
    198 	RVCE_CS(0x00000000); // encEnImeOverwDisSubm
    199 	RVCE_CS(0x00000000); // encImeOverwDisSubmNo
    200 	RVCE_CS(0x00000001); // encIME2SearchRangeX
    201 	RVCE_CS(0x00000001); // encIME2SearchRangeY
    202 	RVCE_CS(0x00000000); // parallelModeSpeedupEnable
    203 	RVCE_CS(0x00000000); // fme0_encDisableSubMode
    204 	RVCE_CS(0x00000000); // fme1_encDisableSubMode
    205 	RVCE_CS(0x00000000); // imeSWSpeedupEnable
    206 	RVCE_END();
    207 }
    208 
    209 static void rdo(struct rvce_encoder *enc)
    210 {
    211 	RVCE_BEGIN(0x04000008); // rdo
    212 	RVCE_CS(0x00000000); // encDisableTbePredIFrame
    213 	RVCE_CS(0x00000000); // encDisableTbePredPFrame
    214 	RVCE_CS(0x00000000); // useFmeInterpolY
    215 	RVCE_CS(0x00000000); // useFmeInterpolUV
    216 	RVCE_CS(0x00000000); // useFmeIntrapolY
    217 	RVCE_CS(0x00000000); // useFmeIntrapolUV
    218 	RVCE_CS(0x00000000); // useFmeInterpolY_1
    219 	RVCE_CS(0x00000000); // useFmeInterpolUV_1
    220 	RVCE_CS(0x00000000); // useFmeIntrapolY_1
    221 	RVCE_CS(0x00000000); // useFmeIntrapolUV_1
    222 	RVCE_CS(0x00000000); // enc16x16CostAdj
    223 	RVCE_CS(0x00000000); // encSkipCostAdj
    224 	RVCE_CS(0x00000000); // encForce16x16skip
    225 	RVCE_CS(0x00000000); // encDisableThresholdCalcA
    226 	RVCE_CS(0x00000000); // encLumaCoeffCost
    227 	RVCE_CS(0x00000000); // encLumaMBCoeffCost
    228 	RVCE_CS(0x00000000); // encChromaCoeffCost
    229 	RVCE_END();
    230 }
    231 
    232 static void vui(struct rvce_encoder *enc)
    233 {
    234 	int i;
    235 
    236 	if (!enc->pic.rate_ctrl.frame_rate_num)
    237 		return;
    238 
    239 	RVCE_BEGIN(0x04000009); // vui
    240 	RVCE_CS(0x00000000); //aspectRatioInfoPresentFlag
    241 	RVCE_CS(0x00000000); //aspectRatioInfo.aspectRatioIdc
    242 	RVCE_CS(0x00000000); //aspectRatioInfo.sarWidth
    243 	RVCE_CS(0x00000000); //aspectRatioInfo.sarHeight
    244 	RVCE_CS(0x00000000); //overscanInfoPresentFlag
    245 	RVCE_CS(0x00000000); //overScanInfo.overscanAppropFlag
    246 	RVCE_CS(0x00000000); //videoSignalTypePresentFlag
    247 	RVCE_CS(0x00000005); //videoSignalTypeInfo.videoFormat
    248 	RVCE_CS(0x00000000); //videoSignalTypeInfo.videoFullRangeFlag
    249 	RVCE_CS(0x00000000); //videoSignalTypeInfo.colorDescriptionPresentFlag
    250 	RVCE_CS(0x00000002); //videoSignalTypeInfo.colorPrim
    251 	RVCE_CS(0x00000002); //videoSignalTypeInfo.transferChar
    252 	RVCE_CS(0x00000002); //videoSignalTypeInfo.matrixCoef
    253 	RVCE_CS(0x00000000); //chromaLocInfoPresentFlag
    254 	RVCE_CS(0x00000000); //chromaLocInfo.chromaLocTop
    255 	RVCE_CS(0x00000000); //chromaLocInfo.chromaLocBottom
    256 	RVCE_CS(0x00000001); //timingInfoPresentFlag
    257 	RVCE_CS(enc->pic.rate_ctrl.frame_rate_den); //timingInfo.numUnitsInTick
    258 	RVCE_CS(enc->pic.rate_ctrl.frame_rate_num * 2); //timingInfo.timeScale;
    259 	RVCE_CS(0x00000001); //timingInfo.fixedFrameRateFlag
    260 	RVCE_CS(0x00000000); //nalHRDParametersPresentFlag
    261 	RVCE_CS(0x00000000); //hrdParam.cpbCntMinus1
    262 	RVCE_CS(0x00000004); //hrdParam.bitRateScale
    263 	RVCE_CS(0x00000006); //hrdParam.cpbSizeScale
    264 	for (i = 0; i < 32; i++) {
    265 		RVCE_CS(0x00000000); //hrdParam.bitRateValueMinus
    266 		RVCE_CS(0x00000000); //hrdParam.cpbSizeValueMinus
    267 		RVCE_CS(0x00000000); //hrdParam.cbrFlag
    268 	}
    269 	RVCE_CS(0x00000017); //hrdParam.initialCpbRemovalDelayLengthMinus1
    270 	RVCE_CS(0x00000017); //hrdParam.cpbRemovalDelayLengthMinus1
    271 	RVCE_CS(0x00000017); //hrdParam.dpbOutputDelayLengthMinus1
    272 	RVCE_CS(0x00000018); //hrdParam.timeOffsetLength
    273 	RVCE_CS(0x00000000); //lowDelayHRDFlag
    274 	RVCE_CS(0x00000000); //picStructPresentFlag
    275 	RVCE_CS(0x00000000); //bitstreamRestrictionPresentFlag
    276 	RVCE_CS(0x00000001); //bitstreamRestrictions.motionVectorsOverPicBoundariesFlag
    277 	RVCE_CS(0x00000002); //bitstreamRestrictions.maxBytesPerPicDenom
    278 	RVCE_CS(0x00000001); //bitstreamRestrictions.maxBitsPerMbDenom
    279 	RVCE_CS(0x00000010); //bitstreamRestrictions.log2MaxMvLengthHori
    280 	RVCE_CS(0x00000010); //bitstreamRestrictions.log2MaxMvLengthVert
    281 	RVCE_CS(0x00000003); //bitstreamRestrictions.numReorderFrames
    282 	RVCE_CS(0x00000003); //bitstreamRestrictions.maxDecFrameBuffering
    283 	RVCE_END();
    284 }
    285 
    286 static void config(struct rvce_encoder *enc)
    287 {
    288 	enc->task_info(enc, 0x00000002, 0, 0xffffffff, 0);
    289 	enc->rate_control(enc);
    290 	enc->config_extension(enc);
    291 	enc->motion_estimation(enc);
    292 	enc->rdo(enc);
    293 	if (enc->use_vui)
    294 		enc->vui(enc);
    295 	enc->pic_control(enc);
    296 }
    297 
    298 static void encode(struct rvce_encoder *enc)
    299 {
    300 	signed luma_offset, chroma_offset;
    301 	int i;
    302 
    303 	enc->task_info(enc, 0x00000003, 0, 0, 0);
    304 
    305 	RVCE_BEGIN(0x05000001); // context buffer
    306 	RVCE_READWRITE(enc->cpb.res->buf, enc->cpb.res->domains, 0x0); // encodeContextAddressHi/Lo
    307 	RVCE_END();
    308 
    309 	RVCE_BEGIN(0x05000004); // video bitstream buffer
    310 	RVCE_WRITE(enc->bs_handle, RADEON_DOMAIN_GTT, 0x0); // videoBitstreamRingAddressHi/Lo
    311 	RVCE_CS(enc->bs_size); // videoBitstreamRingSize
    312 	RVCE_END();
    313 
    314 	RVCE_BEGIN(0x03000001); // encode
    315 	RVCE_CS(0x00000000); // insertHeaders
    316 	RVCE_CS(0x00000000); // pictureStructure
    317 	RVCE_CS(enc->bs_size); // allowedMaxBitstreamSize
    318 	RVCE_CS(0x00000000); // forceRefreshMap
    319 	RVCE_CS(0x00000000); // insertAUD
    320 	RVCE_CS(0x00000000); // endOfSequence
    321 	RVCE_CS(0x00000000); // endOfStream
    322 	RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM,
    323 		  enc->luma->level[0].offset); // inputPictureLumaAddressHi/Lo
    324 	RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM,
    325 		  enc->chroma->level[0].offset); // inputPictureChromaAddressHi/Lo
    326 	RVCE_CS(align(enc->luma->level[0].nblk_y, 16)); // encInputFrameYPitch
    327 	RVCE_CS(enc->luma->level[0].nblk_x * enc->luma->bpe); // encInputPicLumaPitch
    328 	RVCE_CS(enc->chroma->level[0].nblk_x * enc->chroma->bpe); // encInputPicChromaPitch
    329 	RVCE_CS(0x00000000); // encInputPic(Addr|Array)Mode
    330 	RVCE_CS(0x00000000); // encInputPicTileConfig
    331 	RVCE_CS(enc->pic.picture_type); // encPicType
    332 	RVCE_CS(enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_IDR); // encIdrFlag
    333 	RVCE_CS(0x00000000); // encIdrPicId
    334 	RVCE_CS(0x00000000); // encMGSKeyPic
    335 	RVCE_CS(!enc->pic.not_referenced); // encReferenceFlag
    336 	RVCE_CS(0x00000000); // encTemporalLayerIndex
    337 	RVCE_CS(0x00000000); // num_ref_idx_active_override_flag
    338 	RVCE_CS(0x00000000); // num_ref_idx_l0_active_minus1
    339 	RVCE_CS(0x00000000); // num_ref_idx_l1_active_minus1
    340 
    341 	i = enc->pic.frame_num - enc->pic.ref_idx_l0;
    342 	if (i > 1 && enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_P) {
    343 		RVCE_CS(0x00000001); // encRefListModificationOp
    344 		RVCE_CS(i - 1);      // encRefListModificationNum
    345 	} else {
    346 		RVCE_CS(0x00000000); // encRefListModificationOp
    347 		RVCE_CS(0x00000000); // encRefListModificationNum
    348 	}
    349 
    350 	for (i = 0; i < 3; ++i) {
    351 		RVCE_CS(0x00000000); // encRefListModificationOp
    352 		RVCE_CS(0x00000000); // encRefListModificationNum
    353 	}
    354 	for (i = 0; i < 4; ++i) {
    355 		RVCE_CS(0x00000000); // encDecodedPictureMarkingOp
    356 		RVCE_CS(0x00000000); // encDecodedPictureMarkingNum
    357 		RVCE_CS(0x00000000); // encDecodedPictureMarkingIdx
    358 		RVCE_CS(0x00000000); // encDecodedRefBasePictureMarkingOp
    359 		RVCE_CS(0x00000000); // encDecodedRefBasePictureMarkingNum
    360 	}
    361 
    362 	// encReferencePictureL0[0]
    363 	RVCE_CS(0x00000000); // pictureStructure
    364 	if(enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_P ||
    365 	   enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) {
    366 		struct rvce_cpb_slot *l0 = l0_slot(enc);
    367 		rvce_frame_offset(enc, l0, &luma_offset, &chroma_offset);
    368 		RVCE_CS(l0->picture_type); // encPicType
    369 		RVCE_CS(l0->frame_num); // frameNumber
    370 		RVCE_CS(l0->pic_order_cnt); // pictureOrderCount
    371 		RVCE_CS(luma_offset); // lumaOffset
    372 		RVCE_CS(chroma_offset); // chromaOffset
    373 	} else {
    374 		RVCE_CS(0x00000000); // encPicType
    375 		RVCE_CS(0x00000000); // frameNumber
    376 		RVCE_CS(0x00000000); // pictureOrderCount
    377 		RVCE_CS(0xffffffff); // lumaOffset
    378 		RVCE_CS(0xffffffff); // chromaOffset
    379 	}
    380 
    381 	// encReferencePictureL0[1]
    382 	RVCE_CS(0x00000000); // pictureStructure
    383 	RVCE_CS(0x00000000); // encPicType
    384 	RVCE_CS(0x00000000); // frameNumber
    385 	RVCE_CS(0x00000000); // pictureOrderCount
    386 	RVCE_CS(0xffffffff); // lumaOffset
    387 	RVCE_CS(0xffffffff); // chromaOffset
    388 
    389 	// encReferencePictureL1[0]
    390 	RVCE_CS(0x00000000); // pictureStructure
    391 	if(enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) {
    392 		struct rvce_cpb_slot *l1 = l1_slot(enc);
    393 		rvce_frame_offset(enc, l1, &luma_offset, &chroma_offset);
    394 		RVCE_CS(l1->picture_type); // encPicType
    395 		RVCE_CS(l1->frame_num); // frameNumber
    396 		RVCE_CS(l1->pic_order_cnt); // pictureOrderCount
    397 		RVCE_CS(luma_offset); // lumaOffset
    398 		RVCE_CS(chroma_offset); // chromaOffset
    399 	} else {
    400 		RVCE_CS(0x00000000); // encPicType
    401 		RVCE_CS(0x00000000); // frameNumber
    402 		RVCE_CS(0x00000000); // pictureOrderCount
    403 		RVCE_CS(0xffffffff); // lumaOffset
    404 		RVCE_CS(0xffffffff); // chromaOffset
    405 	}
    406 
    407 	rvce_frame_offset(enc, current_slot(enc), &luma_offset, &chroma_offset);
    408 	RVCE_CS(luma_offset); // encReconstructedLumaOffset
    409 	RVCE_CS(chroma_offset); // encReconstructedChromaOffset
    410 	RVCE_CS(0x00000000); // encColocBufferOffset
    411 	RVCE_CS(0x00000000); // encReconstructedRefBasePictureLumaOffset
    412 	RVCE_CS(0x00000000); // encReconstructedRefBasePictureChromaOffset
    413 	RVCE_CS(0x00000000); // encReferenceRefBasePictureLumaOffset
    414 	RVCE_CS(0x00000000); // encReferenceRefBasePictureChromaOffset
    415 	RVCE_CS(0x00000000); // pictureCount
    416 	RVCE_CS(enc->pic.frame_num); // frameNumber
    417 	RVCE_CS(enc->pic.pic_order_cnt); // pictureOrderCount
    418 	RVCE_CS(0x00000000); // numIPicRemainInRCGOP
    419 	RVCE_CS(0x00000000); // numPPicRemainInRCGOP
    420 	RVCE_CS(0x00000000); // numBPicRemainInRCGOP
    421 	RVCE_CS(0x00000000); // numIRPicRemainInRCGOP
    422 	RVCE_CS(0x00000000); // enableIntraRefresh
    423 	RVCE_END();
    424 }
    425 
    426 static void destroy(struct rvce_encoder *enc)
    427 {
    428 	enc->task_info(enc, 0x00000001, 0, 0, 0);
    429 
    430 	RVCE_BEGIN(0x02000001); // destroy
    431 	RVCE_END();
    432 }
    433 
    434 void radeon_vce_40_2_2_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic)
    435 {
    436 }
    437 
    438 void radeon_vce_40_2_2_init(struct rvce_encoder *enc)
    439 {
    440 	enc->session = session;
    441 	enc->task_info = task_info;
    442 	enc->create = create;
    443 	enc->feedback = feedback;
    444 	enc->rate_control = rate_control;
    445 	enc->config_extension = config_extension;
    446 	enc->pic_control = pic_control;
    447 	enc->motion_estimation = motion_estimation;
    448 	enc->rdo = rdo;
    449 	enc->vui = vui;
    450 	enc->config = config;
    451 	enc->encode = encode;
    452 	enc->destroy = destroy;
    453 }
    454