1 /* 2 * Copyright (c) 2021, Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included 12 * in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 //! 23 //! \file encode_huc_la_update_packet.cpp 24 //! \brief Defines the implementation of Huc Lookahead update packet 25 //! 26 27 #include "encode_huc_la_update_packet.h" 28 #include "encode_vdenc_lpla_analysis.h" 29 30 namespace encode 31 { Init()32 MOS_STATUS HucLaUpdatePkt::Init() 33 { 34 ENCODE_FUNC_CALL(); 35 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 36 37 HUC_CHK_STATUS_RETURN(EncodeHucPkt::Init()); 38 39 ENCODE_CHK_NULL_RETURN(m_featureManager); 40 m_basicFeature = dynamic_cast<HevcBasicFeature *>(m_featureManager->GetFeature(HevcFeatureIDs::basicFeature)); 41 ENCODE_CHK_NULL_RETURN(m_basicFeature); 42 43 return eStatus; 44 } 45 AllocateResources()46 MOS_STATUS HucLaUpdatePkt::AllocateResources() 47 { 48 ENCODE_FUNC_CALL(); 49 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 50 51 ENCODE_CHK_STATUS_RETURN(EncodeHucPkt::AllocateResources()); 52 53 return eStatus; 54 } 55 Submit(MOS_COMMAND_BUFFER * commandBuffer,uint8_t packetPhase)56 MOS_STATUS HucLaUpdatePkt::Submit(MOS_COMMAND_BUFFER *commandBuffer, uint8_t packetPhase) 57 { 58 ENCODE_FUNC_CALL(); 59 60 bool firstTaskInPhase = packetPhase & firstPacket; 61 bool requestProlog = false; 62 bool isLaAnalysisRequired = true; 63 64 #if _SW_BRC 65 if (!m_pipeline->IsFirstPass()) 66 { 67 auto pdwData = (uint32_t *)m_allocator->LockResourceForRead(m_basicFeature->m_recycleBuf->GetBuffer(VdencBrcPakMmioBuffer, 0)); 68 ENCODE_CHK_NULL_RETURN(pdwData); 69 isLaAnalysisRequired = (*pdwData == CODECHAL_VDENC_HEVC_BRC_HUC_STATUS_REENCODE_MASK); 70 m_allocator->UnLock(m_basicFeature->m_recycleBuf->GetBuffer(VdencBrcPakMmioBuffer, 0)); 71 72 if (m_swBrc && m_swBrc->SwBrcEnabled() && !isLaAnalysisRequired) 73 { 74 RUN_FEATURE_INTERFACE_RETURN(VdencLplaAnalysis, HevcFeatureIDs::vdencLplaAnalysisFeature, CalculateLaRecords, true); 75 return MOS_STATUS_SUCCESS; 76 } 77 } 78 #endif 79 if (!m_pipeline->IsSingleTaskPhaseSupported() || firstTaskInPhase) 80 { 81 // Send command buffer header at the beginning (OS dependent) 82 requestProlog = true; 83 } 84 85 uint16_t orig_perf_tag = (uint16_t)m_osInterface->pfnGetPerfTag(m_osInterface); 86 SetPerfTag(CODECHAL_ENCODE_PERFTAG_CALL_HEVC_LA_UPDATE, (uint16_t)m_basicFeature->m_mode, (uint16_t)m_basicFeature->m_pictureCodingType); 87 ENCODE_CHK_STATUS_RETURN(Execute(commandBuffer, true, requestProlog, LA_UPDATE)); 88 SetPerfTag(orig_perf_tag, (uint16_t)m_basicFeature->m_mode, (uint16_t)m_basicFeature->m_pictureCodingType); 89 90 #if _SW_BRC 91 if (!m_swBrc || !m_swBrc->SwBrcEnabled()) 92 { 93 #endif 94 if (!m_pipeline->IsLastPass()) 95 { 96 // Write HUC_STATUS mask: DW1 (mask value) 97 auto &storeDataParams = m_miItf->MHW_GETPAR_F(MI_STORE_DATA_IMM)(); 98 storeDataParams = {}; 99 storeDataParams.pOsResource = m_basicFeature->m_recycleBuf->GetBuffer(VdencBrcPakMmioBuffer, 0); 100 storeDataParams.dwResourceOffset = sizeof(uint32_t); 101 storeDataParams.dwValue = CODECHAL_VDENC_HEVC_BRC_HUC_STATUS_REENCODE_MASK; 102 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_DATA_IMM)(commandBuffer)); 103 104 // store HUC_STATUS register: DW0 (actual value) 105 ENCODE_CHK_COND_RETURN((m_vdboxIndex > MHW_VDBOX_NODE_1), "ERROR - vdbox index exceed the maximum"); 106 auto mmioRegisters = m_hucItf->GetMmioRegisters(m_vdboxIndex); 107 auto &storeRegParams = m_miItf->MHW_GETPAR_F(MI_STORE_REGISTER_MEM)(); 108 storeDataParams = {}; 109 storeRegParams.presStoreBuffer = m_basicFeature->m_recycleBuf->GetBuffer(VdencBrcPakMmioBuffer, 0); 110 storeRegParams.dwOffset = 0; 111 storeRegParams.dwRegister = mmioRegisters->hucStatusRegOffset; 112 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_STORE_REGISTER_MEM)(commandBuffer)); 113 } 114 #if _SW_BRC 115 } 116 else 117 { 118 //add force wake up for ladll path, to avoid that ladll path directly use MI_COPY to get data in ReadLPLAData 119 if (requestProlog) 120 { 121 ENCODE_CHK_STATUS_RETURN(AddForceWakeup(*commandBuffer)); 122 ENCODE_CHK_STATUS_RETURN(SendPrologCmds(*commandBuffer)); 123 } 124 } 125 #endif 126 127 ReadLPLAData(commandBuffer); 128 129 RUN_FEATURE_INTERFACE_RETURN(VdencLplaAnalysis, HevcFeatureIDs::vdencLplaAnalysisFeature, CalculateLaRecords, m_pipeline->IsLastPass()); 130 131 return MOS_STATUS_SUCCESS; 132 } 133 CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)134 MOS_STATUS HucLaUpdatePkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize) 135 { 136 ENCODE_FUNC_CALL(); 137 138 auto osInterface = m_hwInterface->GetOsInterface(); 139 ENCODE_CHK_NULL_RETURN(osInterface); 140 141 uint32_t hucCommandsSize = 0; 142 uint32_t hucPatchListSize = 0; 143 MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams; 144 145 ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucStateCommandSize( 146 m_basicFeature->m_mode, (uint32_t *)&hucCommandsSize, (uint32_t *)&hucPatchListSize, &stateCmdSizeParams)); 147 148 commandBufferSize = hucCommandsSize; 149 requestedPatchListSize = osInterface->bUsesPatchList ? hucPatchListSize : 0; 150 151 if (m_pipeline->IsSingleTaskPhaseSupported()) 152 { 153 commandBufferSize *= m_pipeline->GetPassNum(); 154 } 155 156 // 4K align since allocation is in chunks of 4K bytes. 157 commandBufferSize = MOS_ALIGN_CEIL(commandBufferSize, CODECHAL_PAGE_SIZE); 158 159 return MOS_STATUS_SUCCESS; 160 } 161 Completed(void * mfxStatus,void * rcsStatus,void * statusReport)162 MOS_STATUS HucLaUpdatePkt::Completed(void *mfxStatus, void *rcsStatus, void *statusReport) 163 { 164 ENCODE_FUNC_CALL(); 165 166 ENCODE_CHK_NULL_RETURN(mfxStatus); 167 ENCODE_CHK_NULL_RETURN(statusReport); 168 ENCODE_CHK_NULL_RETURN(m_basicFeature); 169 170 ENCODE_CHK_STATUS_RETURN(EncodeHucPkt::Completed(mfxStatus, rcsStatus, statusReport)); 171 172 EncodeStatusMfx * encodeStatusMfx = (EncodeStatusMfx *)mfxStatus; 173 EncodeStatusReportData *statusReportData = (EncodeStatusReportData *)statusReport; 174 175 RUN_FEATURE_INTERFACE_RETURN(VdencLplaAnalysis, HevcFeatureIDs::vdencLplaAnalysisFeature, GetLplaStatusReport, encodeStatusMfx, statusReportData); 176 return MOS_STATUS_SUCCESS; 177 } 178 DumpOutput()179 MOS_STATUS HucLaUpdatePkt::DumpOutput() 180 { 181 ENCODE_FUNC_CALL(); 182 183 #if USE_CODECHAL_DEBUG_TOOL 184 RUN_FEATURE_INTERFACE_RETURN(VdencLplaAnalysis, HevcFeatureIDs::vdencLplaAnalysisFeature, DumpLaResource, m_pipeline, false); 185 #endif 186 187 return MOS_STATUS_SUCCESS; 188 } 189 190 #if USE_CODECHAL_DEBUG_TOOL DumpInput()191 MOS_STATUS HucLaUpdatePkt::DumpInput() 192 { 193 ENCODE_FUNC_CALL(); 194 195 RUN_FEATURE_INTERFACE_RETURN(VdencLplaAnalysis, HevcFeatureIDs::vdencLplaAnalysisFeature, DumpLaResource, m_pipeline, true); 196 197 return MOS_STATUS_SUCCESS; 198 } 199 #endif 200 ReadLPLAData(MOS_COMMAND_BUFFER * commandBuffer)201 MOS_STATUS HucLaUpdatePkt::ReadLPLAData(MOS_COMMAND_BUFFER* commandBuffer) 202 { 203 ENCODE_FUNC_CALL(); 204 205 PMOS_RESOURCE osResource = nullptr; 206 uint32_t offset = 0; 207 208 m_statusReport->GetAddress(statusReportLpla, osResource, offset); 209 210 RUN_FEATURE_INTERFACE_RETURN(VdencLplaAnalysis, HevcFeatureIDs::vdencLplaAnalysisFeature, ReadLPLAData, commandBuffer, osResource, offset); 211 212 return MOS_STATUS_SUCCESS; 213 } 214 MHW_SETPAR_DECL_SRC(HUC_IMEM_STATE,HucLaUpdatePkt)215 MHW_SETPAR_DECL_SRC(HUC_IMEM_STATE, HucLaUpdatePkt) 216 { 217 params.kernelDescriptor = VDBOX_HUC_LA_ANALYSIS_KERNEL_DESCRIPTOR; 218 219 return MOS_STATUS_SUCCESS; 220 } 221 MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE,HucLaUpdatePkt)222 MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE, HucLaUpdatePkt) 223 { 224 params.function = LA_UPDATE; 225 RUN_FEATURE_INTERFACE_RETURN(VdencLplaAnalysis, HevcFeatureIDs::vdencLplaAnalysisFeature, SetLaUpdateDmemParameters, 226 params, m_pipeline->m_currRecycledBufIdx, m_pipeline->GetCurrentPass(), m_pipeline->GetPassNum()); 227 228 auto laAnalysisFeature = dynamic_cast<VdencLplaAnalysis *>(m_featureManager->GetFeature(HevcFeatureIDs::vdencLplaAnalysisFeature)); 229 if (laAnalysisFeature && laAnalysisFeature->IsLastPicInStream()) 230 { 231 m_pipeline->m_currRecycledBufIdx = 232 (m_pipeline->m_currRecycledBufIdx + 1) % CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; 233 } 234 return MOS_STATUS_SUCCESS; 235 } 236 MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE,HucLaUpdatePkt)237 MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE, HucLaUpdatePkt) 238 { 239 params.function = LA_UPDATE; 240 return MOS_STATUS_SUCCESS; 241 } 242 243 } // namespace encode 244