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_skl.cpp
24 //! \brief HEVC dual-pipe encoder for GEN9 SKL.
25 //!
26
27 #include "codechal_encode_hevc_g9_skl.h"
28 #include "igcodeckrn_g9.h"
29
30 //! HEVC encoder kernel header structure for G9 SKL
31 struct CODECHAL_ENC_HEVC_KERNEL_HEADER_G9_SKL
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_SKL
60 using PCODECHAL_ENC_HEVC_KERNEL_HEADER_G9_SKL = struct CODECHAL_ENC_HEVC_KERNEL_HEADER_G9_SKL*;
61
GetKernelHeaderAndSize(void * binary,EncOperation operation,uint32_t krnStateIdx,void * krnHeader,uint32_t * krnSize)62 MOS_STATUS CodechalEncHevcStateG9Skl::GetKernelHeaderAndSize(
63 void *binary,
64 EncOperation operation,
65 uint32_t krnStateIdx,
66 void *krnHeader,
67 uint32_t *krnSize)
68 {
69 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
70
71 CODECHAL_ENCODE_FUNCTION_ENTER;
72
73 CODECHAL_ENCODE_CHK_NULL_RETURN(binary);
74 CODECHAL_ENCODE_CHK_NULL_RETURN(krnHeader);
75 CODECHAL_ENCODE_CHK_NULL_RETURN(krnSize);
76
77 PCODECHAL_ENC_HEVC_KERNEL_HEADER_G9_SKL kernelHeaderTable = (PCODECHAL_ENC_HEVC_KERNEL_HEADER_G9_SKL)binary;
78 PCODECHAL_KERNEL_HEADER currKrnHeader = nullptr;
79
80 if (operation == ENC_SCALING4X)
81 {
82 currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_I_DS4HME;
83 }
84 else if (operation == ENC_ME)
85 {
86 // SKL supports P frame. P HME index CODECHAL_ENCODE_ME_IDX_P is 0 and B HME index CODECHAL_ENCODE_ME_IDX_B is 1
87 if (krnStateIdx == 0)
88 {
89 currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_P_HME;
90 }
91 else
92 {
93 currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_B_HME;
94 }
95 }
96 else if (operation == ENC_BRC)
97 {
98 switch (krnStateIdx)
99 {
100 case CODECHAL_HEVC_BRC_COARSE_INTRA:
101 currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_I_COARSE;
102 break;
103
104 case CODECHAL_HEVC_BRC_INIT:
105 currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_BRC_Init;
106 break;
107
108 case CODECHAL_HEVC_BRC_RESET:
109 currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_BRC_Reset;
110 break;
111
112 case CODECHAL_HEVC_BRC_FRAME_UPDATE:
113 currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_BRC_Update;
114 break;
115
116 case CODECHAL_HEVC_BRC_LCU_UPDATE:
117 currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_BRC_LCU_Update;
118 break;
119
120 default:
121 CODECHAL_ENCODE_ASSERTMESSAGE("Unsupported BRC mode requested");
122 eStatus = MOS_STATUS_INVALID_PARAMETER;
123 return eStatus;
124 }
125 }
126 else if (operation == ENC_MBENC)
127 {
128 switch (krnStateIdx)
129 {
130 case CODECHAL_HEVC_MBENC_2xSCALING:
131 case CODECHAL_HEVC_MBENC_32x32MD:
132 case CODECHAL_HEVC_MBENC_16x16SAD:
133 case CODECHAL_HEVC_MBENC_16x16MD:
134 case CODECHAL_HEVC_MBENC_8x8PU:
135 case CODECHAL_HEVC_MBENC_8x8FMODE:
136 case CODECHAL_HEVC_MBENC_32x32INTRACHECK:
137 case CODECHAL_HEVC_MBENC_BENC:
138 currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_I_2xDownSampling_Kernel;
139 currKrnHeader += krnStateIdx;
140 break;
141
142 case CODECHAL_HEVC_MBENC_BPAK:
143 currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_PB_Pak;
144 break;
145
146 case CODECHAL_HEVC_MBENC_ADV:
147 currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_PB_Adv;
148 break;
149
150 case CODECHAL_HEVC_MBENC_DS_COMBINED:
151 // Ignore this kernel on SKL.
152 *krnSize = 0;
153 return eStatus;
154
155 case CODECHAL_HEVC_MBENC_PENC:
156 currKrnHeader = &kernelHeaderTable->HEVC_LCUEnc_P_MB;
157 break;
158
159 case CODECHAL_HEVC_MBENC_ADV_P:
160 currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_P_Adv;
161 break;
162
163 default:
164 CODECHAL_ENCODE_ASSERTMESSAGE("Unsupported ENC mode requested");
165 eStatus = MOS_STATUS_INVALID_PARAMETER;
166 return eStatus;
167 }
168 }
169 else
170 {
171 CODECHAL_ENCODE_ASSERTMESSAGE("Unsupported ENC mode requested");
172 eStatus = MOS_STATUS_INVALID_PARAMETER;
173 return eStatus;
174 }
175
176 *((PCODECHAL_KERNEL_HEADER)krnHeader) = *currKrnHeader;
177
178 PCODECHAL_KERNEL_HEADER nextKrnHeader = (currKrnHeader + 1);
179 PCODECHAL_KERNEL_HEADER invalidEntry = (PCODECHAL_KERNEL_HEADER)(((uint8_t*)binary) + sizeof(*kernelHeaderTable));
180 uint32_t nextKrnOffset = *krnSize;
181
182 if (nextKrnHeader < invalidEntry)
183 {
184 nextKrnOffset = nextKrnHeader->KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT;
185 }
186 *krnSize = nextKrnOffset - (currKrnHeader->KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT);
187
188 return eStatus;
189 }
190
UpdateSSDSliceCount()191 void CodechalEncHevcStateG9Skl::UpdateSSDSliceCount()
192 {
193 CodechalEncodeHevcBase::UpdateSSDSliceCount();
194
195 uint32_t sliceCount;
196 if (m_frameHeight * m_frameWidth >= 3840 * 2160 && m_targetUsage <= 4)
197 {
198 sliceCount = 0;
199 }
200 else
201 {
202 sliceCount = 2;
203 }
204
205 if (m_osInterface->pfnSetSliceCount)
206 {
207 m_osInterface->pfnSetSliceCount(m_osInterface, &sliceCount);
208 }
209 }
210
Initialize(CodechalSetting * settings)211 MOS_STATUS CodechalEncHevcStateG9Skl::Initialize(CodechalSetting * settings)
212 {
213 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
214
215 CODECHAL_ENCODE_FUNCTION_ENTER;
216
217 // common initilization
218 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncHevcStateG9::Initialize(settings));
219
220 m_cscDsState->EnableMmc();
221
222 return eStatus;
223 }
224
CodechalEncHevcStateG9Skl(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)225 CodechalEncHevcStateG9Skl::CodechalEncHevcStateG9Skl(
226 CodechalHwInterface* hwInterface,
227 CodechalDebugInterface* debugInterface,
228 PCODECHAL_STANDARD_INFO standardInfo)
229 :CodechalEncHevcStateG9(hwInterface, debugInterface, standardInfo)
230 {
231 m_kernelBase = (uint8_t *)IGCODECKRN_G9;
232 pfnGetKernelHeaderAndSize = GetKernelHeaderAndSize;
233 m_noMeKernelForPFrame = false;
234
235 MOS_STATUS eStatus = InitMhw();
236 if (eStatus != MOS_STATUS_SUCCESS)
237 {
238 CODECHAL_ENCODE_ASSERTMESSAGE("HEVC encoder MHW initialization failed.");
239 }
240 }
241
242