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 //!
24 //! \file decode_huc.cpp
25 //! \brief Defines the common interface for decode huc implementation
26 //! \details The decode huc interface is further sub-divided by different huc usage,
27 //! this file is for the base interface which is shared by all.
28 //!
29
30 #include "decode_huc.h"
31 #include "codechal_debug.h"
32 #include "decode_pipeline.h"
33 #include "decode_predication_packet.h"
34 #include "decode_marker_packet.h"
35
36 namespace decode
37 {
38
DecodeHucBasic(MediaPipeline * pipeline,MediaTask * task,CodechalHwInterfaceNext * hwInterface)39 DecodeHucBasic::DecodeHucBasic(MediaPipeline *pipeline, MediaTask *task, CodechalHwInterfaceNext*hwInterface)
40 : CmdPacket(task)
41 {
42 m_pipeline = dynamic_cast<DecodePipeline *>(pipeline);
43 if (m_pipeline != nullptr)
44 {
45 m_featureManager = m_pipeline->GetFeatureManager();
46 m_allocator = m_pipeline->GetDecodeAllocator();
47 m_decodecp = m_pipeline->GetDecodeCp();
48 }
49
50 if (hwInterface != nullptr)
51 {
52 m_hwInterface = hwInterface;
53 m_osInterface = hwInterface->GetOsInterface();
54 m_miItf = std::static_pointer_cast<mhw::mi::Itf>(hwInterface->GetMiInterfaceNext());
55 m_vdencItf = std::static_pointer_cast<mhw::vdbox::vdenc::Itf>(m_hwInterface->GetVdencInterfaceNext());
56 m_hucItf = std::static_pointer_cast<mhw::vdbox::huc::Itf>(m_hwInterface->GetHucInterfaceNext());
57
58 }
59 }
60
~DecodeHucBasic()61 DecodeHucBasic::~DecodeHucBasic()
62 {
63 }
64
Init()65 MOS_STATUS DecodeHucBasic::Init()
66 {
67 DECODE_CHK_NULL(m_pipeline);
68 DECODE_CHK_NULL(m_featureManager);
69 DECODE_CHK_NULL(m_osInterface);
70 DECODE_CHK_NULL(m_hucItf);
71 DECODE_CHK_NULL(m_miItf);
72 DECODE_CHK_NULL(m_vdencItf);
73 m_basicFeature = dynamic_cast<DecodeBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
74 DECODE_CHK_NULL(m_basicFeature);
75
76 DECODE_CHK_STATUS(CmdPacket::Init());
77 DECODE_CHK_STATUS(AllocateResources());
78
79 return MOS_STATUS_SUCCESS;
80 }
81
AllocateResources()82 MOS_STATUS DecodeHucBasic::AllocateResources()
83 {
84 DECODE_CHK_NULL(m_allocator);
85
86 return MOS_STATUS_SUCCESS;
87 }
88
Completed(void * mfxStatus,void * rcsStatus,void * statusReport)89 MOS_STATUS DecodeHucBasic::Completed(void* mfxStatus, void* rcsStatus, void* statusReport)
90 {
91 DECODE_FUNC_CALL();
92
93 DECODE_CHK_NULL(mfxStatus);
94 DECODE_CHK_NULL(statusReport);
95
96 DecodeStatusMfx* decodeStatusMfx = (DecodeStatusMfx*)mfxStatus;
97 DecodeStatusReportData* statusReportData = (DecodeStatusReportData*)statusReport;
98
99 // Print HuC_Status and HuC_Status2 registers
100 DECODE_VERBOSEMESSAGE("Index = %d", statusReportData->currDecodedPic.FrameIdx);
101 DECODE_VERBOSEMESSAGE("HUC_STATUS register = 0x%x",
102 decodeStatusMfx->m_hucErrorStatus >> 32);
103 DECODE_VERBOSEMESSAGE("HUC_STATUS2 register = 0x%x",
104 decodeStatusMfx->m_hucErrorStatus2 >> 32);
105
106 return MOS_STATUS_SUCCESS;
107 }
108
Destroy()109 MOS_STATUS DecodeHucBasic::Destroy()
110 {
111 return MOS_STATUS_SUCCESS;
112 }
113
SetHucStatusMask(uint32_t hucStatusMask,uint32_t hucStatus2Mask)114 void DecodeHucBasic::SetHucStatusMask(uint32_t hucStatusMask, uint32_t hucStatus2Mask)
115 {
116 m_hucStatusMask = hucStatusMask;
117 m_hucStatus2Mask = hucStatus2Mask;
118 }
119
StoreHucStatusRegister(MOS_COMMAND_BUFFER & cmdBuffer)120 MOS_STATUS DecodeHucBasic::StoreHucStatusRegister(MOS_COMMAND_BUFFER& cmdBuffer)
121 {
122 if(m_hucStatusMask == m_hucStatusInvalidMask)
123 {
124 return MOS_STATUS_SUCCESS;
125 }
126
127 MOS_RESOURCE* osResource;
128 uint32_t offset;
129 {
130 DECODE_CHK_STATUS(m_statusReport->GetAddress(decode::DecodeStatusReportType::HucErrorStatusMask, osResource, offset));
131
132 // Write HUC_STATUS mask
133 auto &par = m_miItf->GETPAR_MI_STORE_DATA_IMM();
134 par = {};
135 par.pOsResource = osResource;
136 par.dwResourceOffset = offset;
137 par.dwValue = m_hucStatusMask;
138 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_STORE_DATA_IMM(&cmdBuffer));
139 }
140 {
141 DECODE_CHK_STATUS(m_statusReport->GetAddress(decode::DecodeStatusReportType::HucErrorStatusReg, osResource, offset));
142
143 // Store HUC_STATUS register
144 auto &par = m_miItf->GETPAR_MI_STORE_REGISTER_MEM();
145 par = {};
146 par.presStoreBuffer = osResource;
147 par.dwOffset = offset;
148 par.dwRegister = m_hucItf->GetMmioRegisters(MHW_VDBOX_NODE_1)->hucStatusRegOffset;
149 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_STORE_REGISTER_MEM(&cmdBuffer));
150 }
151
152 return MOS_STATUS_SUCCESS;
153 }
154
StoreHucStatus2Register(MOS_COMMAND_BUFFER & cmdBuffer)155 MOS_STATUS DecodeHucBasic::StoreHucStatus2Register(MOS_COMMAND_BUFFER& cmdBuffer)
156 {
157 if(m_hucStatus2Mask == m_hucStatusInvalidMask)
158 {
159 return MOS_STATUS_SUCCESS;
160 }
161
162 MOS_RESOURCE* osResource;
163 uint32_t offset;
164 {
165 DECODE_CHK_STATUS(m_statusReport->GetAddress(decode::DecodeStatusReportType::HucErrorStatus2Mask, osResource, offset));
166
167 // Write HUC_STATUS2 mask
168 auto &par = m_miItf->GETPAR_MI_STORE_DATA_IMM();
169 par = {};
170 par.pOsResource = osResource;
171 par.dwResourceOffset = offset;
172 par.dwValue = m_hucStatus2Mask;
173 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_STORE_DATA_IMM(&cmdBuffer));
174 }
175 {
176 DECODE_CHK_STATUS(m_statusReport->GetAddress(decode::DecodeStatusReportType::HucErrorStatus2Reg, osResource, offset));
177 // Store HUC_STATUS2 register
178 auto &par = m_miItf->GETPAR_MI_STORE_REGISTER_MEM();
179 par = {};
180 par.presStoreBuffer = osResource;
181 par.dwOffset = offset;
182 par.dwRegister = m_hucItf->GetMmioRegisters(MHW_VDBOX_NODE_1)->hucStatus2RegOffset;
183 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_STORE_REGISTER_MEM(&cmdBuffer));
184 }
185 return MOS_STATUS_SUCCESS;
186 }
187
StartStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)188 MOS_STATUS DecodeHucBasic::StartStatusReport(uint32_t srType, MOS_COMMAND_BUFFER* cmdBuffer)
189 {
190
191 MediaPacket::StartStatusReport(srType, cmdBuffer);
192
193 return MOS_STATUS_SUCCESS;
194 }
195
EndStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)196 MOS_STATUS DecodeHucBasic::EndStatusReport(uint32_t srType, MOS_COMMAND_BUFFER* cmdBuffer)
197 {
198
199 DECODE_FUNC_CALL();
200 DECODE_CHK_NULL(cmdBuffer);
201
202 DECODE_CHK_STATUS(MediaPacket::EndStatusReport(srType, cmdBuffer));
203
204 return MOS_STATUS_SUCCESS;
205
206 }
207
AddForceWakeup(MOS_COMMAND_BUFFER & cmdBuffer,bool mfxWakeup,bool hcpWakeup)208 MOS_STATUS DecodeHucBasic::AddForceWakeup(MOS_COMMAND_BUFFER& cmdBuffer, bool mfxWakeup, bool hcpWakeup)
209 {
210 DECODE_FUNC_CALL();
211
212 auto &par = m_miItf->GETPAR_MI_FORCE_WAKEUP();
213 par = {};
214 par.bMFXPowerWellControl = mfxWakeup;
215 par.bMFXPowerWellControlMask = true;
216 par.bHEVCPowerWellControl = hcpWakeup;
217 par.bHEVCPowerWellControlMask = true;
218
219 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_FORCE_WAKEUP(&cmdBuffer));
220
221 return MOS_STATUS_SUCCESS;
222 }
223
SendPrologCmds(MOS_COMMAND_BUFFER & cmdBuffer)224 MOS_STATUS DecodeHucBasic::SendPrologCmds(MOS_COMMAND_BUFFER& cmdBuffer)
225 {
226 DecodeSubPacket* subPacket = m_pipeline->GetSubPacket(DecodePacketId(m_pipeline, markerSubPacketId));
227 DecodeMarkerPkt *makerPacket = dynamic_cast<DecodeMarkerPkt*>(subPacket);
228 DECODE_CHK_NULL(makerPacket);
229 DECODE_CHK_STATUS(makerPacket->Execute(cmdBuffer));
230
231 #ifdef _MMC_SUPPORTED
232 DecodeMemComp *mmcState = m_pipeline->GetMmcState();
233 bool isMmcEnabled = (mmcState != nullptr && mmcState->IsMmcEnabled());
234 if (isMmcEnabled)
235 {
236 DECODE_CHK_STATUS(mmcState->SendPrologCmd(&cmdBuffer, false));
237 }
238 #endif
239
240 MHW_GENERIC_PROLOG_PARAMS genericPrologParams;
241 MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams));
242 genericPrologParams.pOsInterface = m_osInterface;
243 genericPrologParams.pvMiInterface = nullptr;
244 #ifdef _MMC_SUPPORTED
245 genericPrologParams.bMmcEnabled = isMmcEnabled;
246 #endif
247 DECODE_CHK_STATUS(Mhw_SendGenericPrologCmdNext(&cmdBuffer, &genericPrologParams, m_miItf));
248
249 subPacket = m_pipeline->GetSubPacket(DecodePacketId(m_pipeline, predicationSubPacketId));
250 DecodePredicationPkt *predicationPacket = dynamic_cast<DecodePredicationPkt*>(subPacket);
251 DECODE_CHK_NULL(predicationPacket);
252 DECODE_CHK_STATUS(predicationPacket->Execute(cmdBuffer));
253
254 return MOS_STATUS_SUCCESS;
255 }
256
MemoryFlush(MOS_COMMAND_BUFFER & cmdBuffer)257 MOS_STATUS DecodeHucBasic::MemoryFlush(MOS_COMMAND_BUFFER &cmdBuffer)
258 {
259 auto &par = m_miItf->GETPAR_MI_FLUSH_DW();
260 par = {};
261 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_FLUSH_DW(&cmdBuffer));
262 return MOS_STATUS_SUCCESS;
263 }
264
265 }
266