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