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