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_glk.cpp
24 //! \brief    HEVC dual-pipe encoder for GEN9 GLK.
25 //!
26 
27 #include "codechal_encode_hevc_g9_glk.h"
28 //#include "igcodeckrn_g9_bxt.h"
29 #include "igcodeckrn_g9.h"
30 
31 //! HEVC encoder kernel header structure for G9 GLK
32 struct CODECHAL_ENC_HEVC_KERNEL_HEADER_G9_GLK
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_GLK
61 using PCODECHAL_ENC_HEVC_KERNEL_HEADER_G9_GLK = struct CODECHAL_ENC_HEVC_KERNEL_HEADER_G9_GLK*;
62 
CheckSupportedColorFormat(PMOS_SURFACE surface)63 bool CodechalEncHevcStateG9Glk::CheckSupportedColorFormat(
64     PMOS_SURFACE surface)
65 {
66     CODECHAL_ENCODE_FUNCTION_ENTER;
67 
68     if (!surface)
69     {
70         return false;
71     }
72 
73     bool isColorFormatSupported = false;
74     if (surface->TileType == MOS_TILE_Y)
75     {
76         switch (surface->Format)
77         {
78         case Format_NV12:
79         case Format_P010:       // Planar 4:2:0, 10b
80             isColorFormatSupported = true;
81             break;
82 
83         default:
84             break;
85         }
86     }
87 
88     return isColorFormatSupported;
89 }
90 
GetKernelHeaderAndSize(void * binary,EncOperation operation,uint32_t krnStateIdx,void * krnHeader,uint32_t * krnSize)91 MOS_STATUS CodechalEncHevcStateG9Glk::GetKernelHeaderAndSize(
92     void                           *binary,
93     EncOperation                   operation,
94     uint32_t                       krnStateIdx,
95     void                           *krnHeader,
96     uint32_t                       *krnSize)
97 {
98     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
99 
100     CODECHAL_ENCODE_FUNCTION_ENTER;
101 
102     CODECHAL_ENCODE_CHK_NULL_RETURN(binary);
103     CODECHAL_ENCODE_CHK_NULL_RETURN(krnHeader);
104     CODECHAL_ENCODE_CHK_NULL_RETURN(krnSize);
105 
106     PCODECHAL_ENC_HEVC_KERNEL_HEADER_G9_GLK kernelHeaderTable = (PCODECHAL_ENC_HEVC_KERNEL_HEADER_G9_GLK)binary;
107     PCODECHAL_KERNEL_HEADER currKrnHeader = nullptr;
108 
109     if (operation == ENC_SCALING4X)
110     {
111         currKrnHeader = &kernelHeaderTable->Hevc_LCUEnc_I_DS4HME;
112     }
113     else if (operation == ENC_ME)
114     {
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 
CodechalEncHevcStateG9Glk(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)218 CodechalEncHevcStateG9Glk::CodechalEncHevcStateG9Glk(
219     CodechalHwInterface* hwInterface,
220     CodechalDebugInterface* debugInterface,
221     PCODECHAL_STANDARD_INFO standardInfo)
222     :CodechalEncHevcStateG9(hwInterface, debugInterface, standardInfo)
223 {
224     //m_kernelBase = (uint8_t *)IGCODECKRN_G9_BXT;
225     m_kernelBase = (uint8_t *)IGCODECKRN_G9;
226     pfnGetKernelHeaderAndSize = GetKernelHeaderAndSize;
227     m_noMeKernelForPFrame     = false;
228     m_numRegionsInSlice       = 2;  // GLK has the same setting as BXT/APL
229 
230     MOS_STATUS eStatus = InitMhw();
231     if (eStatus != MOS_STATUS_SUCCESS)
232     {
233         CODECHAL_ENCODE_ASSERTMESSAGE("HEVC encoder MHW initialization failed.");
234     }
235 }
236 
237