1 /*
2 * Copyright (c) 2017, 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_hevc_g9_bxt.cpp
24 //! \brief    HEVC dual-pipe encoder for GEN9 BXT.
25 //!
26 
27 #include "codechal_encode_hevc_g9_bxt.h"
28 //#include "igcodeckrn_g9_bxt.h"
29 #include "igcodeckrn_g9.h"
30 
31 //! HEVC encoder kernel header structure for G9 BXT
32 struct CODECHAL_ENC_HEVC_KERNEL_HEADER_G9_BXT
33 {
34     int nKernelCount;                                                       //!< Total number of kernels
35 
36     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_I_2xDownSampling_Kernel;             //!< 2x down sampling kernel
37     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_I_32x32_PU_ModeDecision_Kernel;      //!< Intra 32x32 PU mode decision kernel
38     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_I_16x16_PU_SADComputation_Kernel;    //!< Intra 16x16 PU SAD computation kernel
39     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_I_16x16_PU_ModeDecision_Kernel;      //!< Intra 16x16 PU mode decision kernel
40     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_I_8x8_PU_Kernel;                     //!< Intra 8x8 PU mode decision kernel
41     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_I_8x8_PU_FMode_Kernel;               //!< Intra 8x8 PU final mode decision kernel
42     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_PB_32x32_PU_IntraCheck;              //!< P/B 32x32 PU intra mode check kernel
43     CODECHAL_KERNEL_HEADER HEVC_LCUEnc_PB_MB;                               //!< P/B MbEnc Kernel
44     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_I_DS4HME;                            //!< 4x Scaling kernel
45     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_P_HME;                               //!< P frame HME kernel
46     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_B_HME;                               //!< B frame HME kernel
47     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_I_COARSE;                            //!< Intra coarse kernel
48     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_BRC_Init;                            //!< BRC init kernel
49     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_BRC_Reset;                           //!< BRC reset kernel
50     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_BRC_Update;                          //!< BRC update kernel
51     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_BRC_LCU_Update;                      //!< BRC LCU update kernel
52     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_PB_Pak;                              //!< P/B frame PAK kernel
53     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_PB_Adv;                              //!< P/B frame Adv kernel
54     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_BRC_Blockcopy;                       //!< BRC blockcopy kerenel
55     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_DS_Combined;                         //!< Down scale and format conversion kernel
56     CODECHAL_KERNEL_HEADER HEVC_LCUEnc_P_MB;                                //!< P frame MbEnc kernel
57     CODECHAL_KERNEL_HEADER Hevc_LCUEnc_P_Adv;                               //!< P frame Adv kernel
58 };
59 
60 //! \brief  typedef of struct CODECHAL_ENC_HEVC_KERNEL_HEADER_G9_BXT
61 using PCODECHAL_ENC_HEVC_KERNEL_HEADER_G9_BXT = struct CODECHAL_ENC_HEVC_KERNEL_HEADER_G9_BXT*;
62 
GetKernelHeaderAndSize(void * binary,EncOperation operation,uint32_t krnStateIdx,void * krnHeader,uint32_t * krnSize)63 MOS_STATUS CodechalEncHevcStateG9Bxt::GetKernelHeaderAndSize(
64     void                           *binary,
65     EncOperation                   operation,
66     uint32_t                       krnStateIdx,
67     void                           *krnHeader,
68     uint32_t                       *krnSize)
69 {
70     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
71 
72     CODECHAL_ENCODE_CHK_NULL_RETURN(binary);
73     CODECHAL_ENCODE_CHK_NULL_RETURN(krnHeader);
74     CODECHAL_ENCODE_CHK_NULL_RETURN(krnSize);
75 
76     PCODECHAL_ENC_HEVC_KERNEL_HEADER_G9_BXT kernelHeaderTable = (PCODECHAL_ENC_HEVC_KERNEL_HEADER_G9_BXT)binary;
77     uint32_t nextKrnOffset = *krnSize;
78 
79     PCODECHAL_KERNEL_HEADER currKrnHeader = nullptr;
80     if (operation == ENC_SCALING2X)
81     {
82         currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_I_2xDownSampling_Kernel;
83     }
84     else if (operation == ENC_SCALING4X)
85     {
86         currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_I_DS4HME;
87     }
88     else if (operation == ENC_ME)
89     {
90         // Only BXT supports P frame. P HME index CODECHAL_ENCODE_ME_IDX_P is 0 and B HME index CODECHAL_ENCODE_ME_IDX_B is 1
91         // Use kernel total number to check if P frame is supported
92         // MBEnc kernels + BRC kernels + DownSampling kernel + DS combined kernel
93         if (kernelHeaderTable->nKernelCount == (CODECHAL_HEVC_MBENC_NUM_BXT_SKL + CODECHAL_HEVC_BRC_NUM + 2))
94         {
95             if (krnStateIdx == 0)
96             {
97                 currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_P_HME;
98             }
99             else
100             {
101                 currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_B_HME;
102             }
103         }
104         else
105         {
106             currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_B_HME;
107         }
108     }
109     else if (operation == ENC_BRC)
110     {
111         switch (krnStateIdx)
112         {
113         case CODECHAL_HEVC_BRC_COARSE_INTRA:
114             currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_I_COARSE;
115             break;
116 
117         case CODECHAL_HEVC_BRC_INIT:
118             currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_BRC_Init;
119             break;
120 
121         case CODECHAL_HEVC_BRC_RESET:
122             currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_BRC_Reset;
123             break;
124 
125         case CODECHAL_HEVC_BRC_FRAME_UPDATE:
126             currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_BRC_Update;
127             break;
128 
129         case CODECHAL_HEVC_BRC_LCU_UPDATE:
130             currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_BRC_LCU_Update;
131             break;
132 
133         default:
134             CODECHAL_ENCODE_ASSERTMESSAGE("Unsupported BRC mode requested");
135             eStatus = MOS_STATUS_INVALID_PARAMETER;
136             return eStatus;
137         }
138     }
139     else if (operation == ENC_MBENC)
140     {
141         switch (krnStateIdx)
142         {
143         case CODECHAL_HEVC_MBENC_2xSCALING:
144         case CODECHAL_HEVC_MBENC_32x32MD:
145         case CODECHAL_HEVC_MBENC_16x16SAD:
146         case CODECHAL_HEVC_MBENC_16x16MD:
147         case CODECHAL_HEVC_MBENC_8x8PU:
148         case CODECHAL_HEVC_MBENC_8x8FMODE:
149         case CODECHAL_HEVC_MBENC_32x32INTRACHECK:
150         case CODECHAL_HEVC_MBENC_BENC:
151             currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_I_2xDownSampling_Kernel;
152             currKrnHeader += krnStateIdx;
153             break;
154 
155         case CODECHAL_HEVC_MBENC_BPAK:
156             currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_PB_Pak;
157             break;
158 
159         case CODECHAL_HEVC_MBENC_ADV:
160             currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_PB_Adv;
161             break;
162 
163         case CODECHAL_HEVC_MBENC_DS_COMBINED:
164             // Ignore this kernel on BXT.
165             *krnSize = 0;
166             return eStatus;
167 
168         case CODECHAL_HEVC_MBENC_PENC:
169             currKrnHeader = &kernelHeaderTable->HEVC_LCUEnc_P_MB;
170             break;
171 
172         case CODECHAL_HEVC_MBENC_ADV_P:
173             currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_P_Adv;
174             break;
175 
176         default:
177             CODECHAL_ENCODE_ASSERTMESSAGE("Unsupported ENC mode requested");
178             eStatus = MOS_STATUS_INVALID_PARAMETER;
179             return eStatus;
180         }
181     }
182     else
183     {
184         CODECHAL_ENCODE_ASSERTMESSAGE("Unsupported ENC mode requested");
185         eStatus = MOS_STATUS_INVALID_PARAMETER;
186         return eStatus;
187     }
188 
189     *((PCODECHAL_KERNEL_HEADER)krnHeader) = *currKrnHeader;
190 
191     PCODECHAL_KERNEL_HEADER nextKrnHeader = (currKrnHeader + 1);
192     PCODECHAL_KERNEL_HEADER invalidEntry = (PCODECHAL_KERNEL_HEADER)(((uint8_t*)binary) + sizeof(*kernelHeaderTable));
193     if (nextKrnHeader < invalidEntry)
194     {
195         nextKrnOffset = nextKrnHeader->KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT;
196     }
197     *krnSize = nextKrnOffset - (currKrnHeader->KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT);
198 
199     return eStatus;
200 }
201 
Initialize(CodechalSetting * settings)202 MOS_STATUS CodechalEncHevcStateG9Bxt::Initialize(CodechalSetting * settings)
203 {
204     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
205 
206     CODECHAL_ENCODE_FUNCTION_ENTER;
207 
208     // common initilization
209     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncHevcStateG9::Initialize(settings));
210 
211     m_cscDsState->EnableMmc();
212 
213     return eStatus;
214 }
215 
CodechalEncHevcStateG9Bxt(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)216 CodechalEncHevcStateG9Bxt::CodechalEncHevcStateG9Bxt(
217     CodechalHwInterface* hwInterface,
218     CodechalDebugInterface* debugInterface,
219     PCODECHAL_STANDARD_INFO standardInfo)
220     :CodechalEncHevcStateG9(hwInterface, debugInterface, standardInfo)
221 {
222     //m_kernelBase = (uint8_t *)IGCODECKRN_G9_BXT;
223     m_kernelBase = (uint8_t *)IGCODECKRN_G9; //IGCODECKRN_G9_BXT causes GPU HANG, use IGCODECKRN_G9.
224     pfnGetKernelHeaderAndSize = GetKernelHeaderAndSize;
225     m_noMeKernelForPFrame = false;
226 
227     m_numRegionsInSlice = 2;
228 
229     MOS_STATUS eStatus = InitMhw();
230     if (eStatus != MOS_STATUS_SUCCESS)
231     {
232         CODECHAL_ENCODE_ASSERTMESSAGE("HEVC encoder MHW initialization failed.");
233     }
234 }
235 
236