1 /*
2 * Copyright (c) 2018, 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 codechal_encode_scalability.cpp
24 //! \brief Implements the encode interface extension for encode scalability.
25 //! \details Implements all functions required by CodecHal for scalability encoding.
26 //!
27
28 #include "codechal_encoder_base.h"
29 #include "codechal_encode_scalability.h"
30 #include "mos_util_user_interface.h"
31 #include "mos_os_virtualengine_next.h"
32
CodecHalEncodeScalability_InitializeState(PCODECHAL_ENCODE_SCALABILITY_STATE pScalabilityState,CodechalHwInterface * hwInterface)33 MOS_STATUS CodecHalEncodeScalability_InitializeState (
34 PCODECHAL_ENCODE_SCALABILITY_STATE pScalabilityState,
35 CodechalHwInterface *hwInterface)
36 {
37 PMOS_VIRTUALENGINE_INTERFACE pVEInterface;
38 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
39 PMOS_INTERFACE osInterface;
40
41 CODECHAL_ENCODE_FUNCTION_ENTER;
42
43 CODECHAL_ENCODE_CHK_NULL_RETURN(pScalabilityState);
44 CODECHAL_ENCODE_CHK_NULL_RETURN(hwInterface);
45 osInterface = hwInterface->GetOsInterface();
46 CODECHAL_ENCODE_CHK_NULL_RETURN(osInterface);
47
48 pScalabilityState->pHwInterface = hwInterface;
49 pScalabilityState->ucScalablePipeNum = 1;
50 pScalabilityState->VideoContextSinglePipe = MOS_GPU_CONTEXT_VIDEO3;
51 pScalabilityState->VideoContextScalable = MOS_GPU_CONTEXT_INVALID_HANDLE;
52
53 //virtual engine init with scalability
54 MOS_VIRTUALENGINE_INIT_PARAMS VEInitParms;
55 MOS_ZeroMemory(&VEInitParms, sizeof(VEInitParms));
56 VEInitParms.bScalabilitySupported = true;
57
58 // Disabling the Secondary command buffer creation in MOS_VE
59 // To be programmed once Encode moves to using secondary command buffers in MOS VE interface
60 VEInitParms.ucMaxNumOfSdryCmdBufInOneFrame = VEInitParms.ucNumOfSdryCmdBufSets = 0;
61 VEInitParms.ucMaxNumPipesInUse = MOS_MAX_ENGINE_INSTANCE_PER_CLASS;
62
63 CODECHAL_ENCODE_CHK_STATUS_RETURN(osInterface->pfnVirtualEngineInterfaceInitialize(osInterface, &VEInitParms));
64 pScalabilityState->pVEInterface = pVEInterface = osInterface->pVEInterf;
65
66 if (pVEInterface->pfnVEGetHintParams)
67 {
68 CODECHAL_ENCODE_CHK_STATUS_RETURN(pVEInterface->pfnVEGetHintParams(pVEInterface, true, &pScalabilityState->pScalHintParms));
69 }
70
71 if (pVEInterface->pfnVEGetHintParams)
72 {
73 CODECHAL_ENCODE_CHK_STATUS_RETURN(pVEInterface->pfnVEGetHintParams(pVEInterface, false, &pScalabilityState->pSingleHintParms));
74 }
75
76 return eStatus;
77 }
78
CodechalEncodeScalability_ConstructParmsForGpuCtxCreation(PCODECHAL_ENCODE_SCALABILITY_STATE pScalState,PMOS_GPUCTX_CREATOPTIONS_ENHANCED gpuCtxCreatOpts)79 MOS_STATUS CodechalEncodeScalability_ConstructParmsForGpuCtxCreation(
80 PCODECHAL_ENCODE_SCALABILITY_STATE pScalState,
81 PMOS_GPUCTX_CREATOPTIONS_ENHANCED gpuCtxCreatOpts)
82 {
83 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
84
85 CODECHAL_ENCODE_FUNCTION_ENTER;
86
87 CODECHAL_ENCODE_CHK_NULL_RETURN(pScalState);
88 CODECHAL_ENCODE_CHK_NULL_RETURN(pScalState->pHwInterface);
89 CODECHAL_ENCODE_CHK_NULL_RETURN(gpuCtxCreatOpts);
90
91 gpuCtxCreatOpts->UsingSFC = false;
92 gpuCtxCreatOpts->LRCACount = pScalState->ucScalablePipeNum;
93
94 #if (_DEBUG || _RELEASE_INTERNAL)
95 PMOS_INTERFACE pOsInterface = pScalState->pHwInterface->GetOsInterface();
96 CODECHAL_ENCODE_CHK_NULL_RETURN(pOsInterface);
97
98 if (pOsInterface->bEnableDbgOvrdInVE)
99 {
100 PMOS_VIRTUALENGINE_INTERFACE pVEInterface = pScalState->pVEInterface;
101
102 CODECHAL_ENCODE_CHK_NULL_RETURN(pVEInterface);
103 gpuCtxCreatOpts->DebugOverride = true;
104 if (pOsInterface->apoMosEnabled)
105 {
106 CODECHAL_ENCODE_CHK_NULL_RETURN(pVEInterface->veInterface);
107 for (uint32_t i = 0; i < pVEInterface->veInterface->GetEngineCount(); i++)
108 {
109 gpuCtxCreatOpts->EngineInstance[i] = pVEInterface->veInterface->GetEngineLogicId(i);
110 }
111 }
112 else
113 {
114 for (uint32_t i = 0; i < pVEInterface->ucEngineCount; i++)
115 {
116 gpuCtxCreatOpts->EngineInstance[i] = pVEInterface->EngineLogicId[i];
117 }
118 }
119
120 }
121 #endif
122 return eStatus;
123 }
124
CodecHalEncodeScalability_PopulateHintParams(PCODECHAL_ENCODE_SCALABILITY_STATE pScalabilityState,PMOS_COMMAND_BUFFER cmdBuffer)125 MOS_STATUS CodecHalEncodeScalability_PopulateHintParams(
126 PCODECHAL_ENCODE_SCALABILITY_STATE pScalabilityState,
127 PMOS_COMMAND_BUFFER cmdBuffer)
128 {
129 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
130
131 CODECHAL_ENCODE_FUNCTION_ENTER;
132
133 CODECHAL_ENCODE_CHK_NULL_RETURN(pScalabilityState);
134 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
135 PMOS_CMD_BUF_ATTRI_VE pAttriVe = (PMOS_CMD_BUF_ATTRI_VE)(cmdBuffer->Attributes.pAttriVe);
136
137 if (pAttriVe)
138 {
139 if (pScalabilityState->ucScalablePipeNum >= 2)
140 {
141 CODECHAL_ENCODE_CHK_NULL_RETURN(pScalabilityState->pScalHintParms);
142 pAttriVe->VEngineHintParams = *(pScalabilityState->pScalHintParms);
143 }
144 else
145 {
146 CODECHAL_ENCODE_CHK_NULL_RETURN(pScalabilityState->pSingleHintParms);
147 pAttriVe->VEngineHintParams = *(pScalabilityState->pSingleHintParms);
148 }
149 pAttriVe->bUseVirtualEngineHint = true;
150 }
151
152 return eStatus;
153 }
154
CodecHalEncodeScalability_SetHintParams(CodechalEncoderState * pEncoder,PCODECHAL_ENCODE_SCALABILITY_STATE pScalabilityState,PCODECHAL_ENCODE_SCALABILITY_SETHINT_PARMS pSetHintParms)155 MOS_STATUS CodecHalEncodeScalability_SetHintParams(
156 CodechalEncoderState *pEncoder,
157 PCODECHAL_ENCODE_SCALABILITY_STATE pScalabilityState,
158 PCODECHAL_ENCODE_SCALABILITY_SETHINT_PARMS pSetHintParms)
159 {
160 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
161 PMOS_INTERFACE pOsInterface;
162
163 CODECHAL_ENCODE_FUNCTION_ENTER;
164
165 CODECHAL_ENCODE_CHK_NULL_RETURN(pScalabilityState);
166 CODECHAL_ENCODE_CHK_NULL_RETURN(pSetHintParms);
167 CODECHAL_ENCODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface);
168 CODECHAL_ENCODE_CHK_NULL_RETURN(pScalabilityState->pHwInterface->GetOsInterface());
169
170 pOsInterface = pScalabilityState->pHwInterface->GetOsInterface();
171 PMOS_VIRTUALENGINE_INTERFACE pVEInterface = pScalabilityState->pVEInterface;
172
173 MOS_VIRTUALENGINE_SET_PARAMS VEParams;
174 MOS_ZeroMemory(&VEParams, sizeof(VEParams));
175
176 VEParams.ucScalablePipeNum = pScalabilityState->ucScalablePipeNum;
177 VEParams.bScalableMode = (pScalabilityState->ucScalablePipeNum >= 2);
178
179 if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(pOsInterface))
180 {
181 //not used by VE2.0
182 VEParams.bNeedSyncWithPrevious = pSetHintParms->bNeedSyncWithPrevious;
183 VEParams.bSameEngineAsLastSubmission = pSetHintParms->bSameEngineAsLastSubmission;
184 }
185
186 if (pScalabilityState->ucScalablePipeNum >= 2)
187 {
188 for (auto i = 0; i < pScalabilityState->ucScalablePipeNum; i++)
189 {
190 VEParams.veBatchBuffer[i] = pSetHintParms->veBatchBuffer[i];
191 }
192 }
193 if (pVEInterface->pfnVESetHintParams)
194 {
195 CODECHAL_ENCODE_CHK_STATUS_RETURN(pVEInterface->pfnVESetHintParams(pVEInterface, &VEParams));
196 }
197
198 return eStatus;
199 }
200
CodechalEncodeScalability_ChkGpuCtxReCreation(CodechalEncoderState * pEncoder,PCODECHAL_ENCODE_SCALABILITY_STATE pScalabilityState,PMOS_GPUCTX_CREATOPTIONS_ENHANCED CurgpuCtxCreatOpts)201 MOS_STATUS CodechalEncodeScalability_ChkGpuCtxReCreation(
202 CodechalEncoderState *pEncoder,
203 PCODECHAL_ENCODE_SCALABILITY_STATE pScalabilityState,
204 PMOS_GPUCTX_CREATOPTIONS_ENHANCED CurgpuCtxCreatOpts)
205 {
206 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
207 PMOS_INTERFACE pOsInterface;
208
209 CODECHAL_ENCODE_FUNCTION_ENTER;
210
211 CODECHAL_ENCODE_CHK_NULL_RETURN(pScalabilityState);
212 CODECHAL_ENCODE_CHK_NULL_RETURN(CurgpuCtxCreatOpts);
213
214 pOsInterface = pScalabilityState->pHwInterface->GetOsInterface();
215 bool changed = false;
216 CODECHAL_ENCODE_CHK_NULL_RETURN(pOsInterface);
217
218 #if (_DEBUG || _RELEASE_INTERNAL)
219 if (pOsInterface->bEnableDbgOvrdInVE)
220 {
221 changed = false;
222 }
223 else
224 #endif
225 {
226 if (CurgpuCtxCreatOpts->LRCACount != pScalabilityState->ucScalablePipeNum)
227 {
228 changed = true;
229 CurgpuCtxCreatOpts->LRCACount = pScalabilityState->ucScalablePipeNum;
230 }
231 else
232 {
233 changed = false;
234 }
235 }
236
237 if (changed)
238 {
239 // Create a scalable GPU context once based on MOS_GPU_CONTEXT_VDBOX2_VIDEO3 if needed
240 if (pScalabilityState->VideoContextScalable == MOS_GPU_CONTEXT_INVALID_HANDLE)
241 {
242 pScalabilityState->VideoContextScalable = MOS_VE_MULTINODESCALING_SUPPORTED(pOsInterface) ? MOS_GPU_CONTEXT_VIDEO6 : MOS_GPU_CONTEXT_VDBOX2_VIDEO3;
243
244 eStatus = (MOS_STATUS)pOsInterface->pfnCreateGpuContext(
245 pOsInterface,
246 pScalabilityState->VideoContextScalable,
247 MOS_GPU_NODE_VIDEO,
248 CurgpuCtxCreatOpts);
249
250 CODECHAL_ENCODE_CHK_STATUS_RETURN(pOsInterface->pfnRegisterBBCompleteNotifyEvent(
251 pOsInterface,
252 pScalabilityState->VideoContextScalable));
253 }
254
255 // Switch across single pipe/ scalable mode gpu contexts
256 MOS_GPU_CONTEXT GpuContext = (pScalabilityState->ucScalablePipeNum == 1) ? pScalabilityState->VideoContextSinglePipe : pScalabilityState->VideoContextScalable;
257 pEncoder->SetVideoContext(GpuContext);
258 pOsInterface->pfnSetEncodePakContext(pOsInterface, GpuContext);
259
260 }
261
262 return eStatus;
263 }
264
CodecHalEncodeScalability_EncodePhaseToSubmissionType(bool isFirstPipe,PMOS_COMMAND_BUFFER pCmdBuffer)265 void CodecHalEncodeScalability_EncodePhaseToSubmissionType(
266 bool isFirstPipe,
267 PMOS_COMMAND_BUFFER pCmdBuffer)
268 {
269 if (isFirstPipe)
270 {
271 pCmdBuffer->iSubmissionType = SUBMISSION_TYPE_MULTI_PIPE_MASTER;
272 }
273 else
274 {
275 pCmdBuffer->iSubmissionType = SUBMISSION_TYPE_MULTI_PIPE_SLAVE;
276 }
277 }
278