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