1 /*
2 * Copyright (c) 2014-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 //!
24 //! \file codechal_decode_vc1_g8.cpp
25 //! \brief Implements the decode interface extension for Gen8 VC1.
26 //! \details Implements all functions required by CodecHal for Gen8 VC1 decoding.
27 //!
28
29 #include "codeckrnheader.h"
30 #include "igcodeckrn_g8.h"
31 #include "codechal_decode_vc1_g8.h"
32
33 const CODECHAL_DECODE_VC1_OLP_STATIC_DATA_G8 g_cInit_CODECHAL_DECODE_VC1_OLP_STATIC_DATA_G8 =
34 {
35 // uint32_t 0
36 {
37 { 0 }
38 },
39
40 // uint32_t 1
41 {
42 {
43 16, // BlockWidth in Byte
44 16 // BlockHeight in Byte
45 }
46 },
47
48 // uint32_t 2
49 {
50 {
51 0, // Profile
52 0, // RangeExpansionFlag
53 0, // UpsamplingFlag
54 0, // InterlaceFieldFlag
55 0, // RangeMapUV
56 0, // RangeMapUVFlag
57 0, // RangeMapY
58 0, // RangeMapYFlag
59 0 // ComponentFlag
60 }
61 },
62
63 // uint32_t 3
64 {
65 { 0 } // Reserved
66 },
67
68 // uint32_t 4
69 {
70 { 0 } // Reserved
71 },
72
73 // uint32_t 5
74 {
75 { 0 } // Reserved
76 },
77
78 // uint32_t 6
79 {
80 { 0 } // Reserved
81 },
82
83 // uint32_t 7
84 {
85 { 0 } // Reserved
86 }
87 };
88
89 const CODECHAL_DECODE_VC1_OLP_INLINE_DATA_G8 g_cInit_CODECHAL_DECODE_VC1_OLP_INLINE_DATA_G8 =
90 {
91 // uint32_t 0
92 {
93 {
94 0, // BlockOriginY
95 0 // BlockOriginX
96 }
97 },
98
99 // uint32_t 1
100 {
101 { 0 } // ComponentFlag
102 },
103
104 // uint32_t 2
105 {
106 {
107 0, // SourceDataBindingIndex
108 0 // DestDataBindingIndex
109 }
110 },
111
112 // uint32_t 3 - 7
113 {
114 0 // Reserved
115 },
116 };
117
SetCurbeOlp()118 MOS_STATUS CodechalDecodeVc1G8::SetCurbeOlp()
119 {
120 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
121
122 CODECHAL_DECODE_CHK_NULL_RETURN(m_hwInterface->GetRenderInterface());
123 CODECHAL_DECODE_CHK_NULL_RETURN(m_hwInterface->GetRenderInterface()->m_stateHeapInterface);
124
125 CODECHAL_DECODE_VC1_OLP_STATIC_DATA_G8 cmd = g_cInit_CODECHAL_DECODE_VC1_OLP_STATIC_DATA_G8;
126
127 cmd.DW2.InterlaceFieldFlag = CodecHal_PictureIsField(m_vc1PicParams->CurrPic);
128 cmd.DW2.PictureUpsamplingFlag = m_vc1PicParams->UpsamplingFlag;
129 cmd.DW2.RangeExpansionFlag = (m_vc1PicParams->range_mapping_fields.range_mapping_enabled != 0);
130 cmd.DW2.Profile = m_vc1PicParams->sequence_fields.AdvancedProfileFlag;
131
132 if (m_vc1PicParams->sequence_fields.AdvancedProfileFlag)
133 {
134 cmd.DW2.RangeMapUV = m_vc1PicParams->range_mapping_fields.chroma;
135 cmd.DW2.RangeMapUVFlag = m_vc1PicParams->range_mapping_fields.chroma_flag;
136 cmd.DW2.RangeMapY = m_vc1PicParams->range_mapping_fields.luma;
137 cmd.DW2.RangeMapYFlag = m_vc1PicParams->range_mapping_fields.luma_flag;
138 }
139
140 CODECHAL_DECODE_CHK_STATUS_RETURN(m_olpKernelState.m_dshRegion.AddData(
141 &cmd,
142 m_olpKernelState.dwCurbeOffset,
143 sizeof(cmd)));
144
145 return eStatus;
146 }
147
AddVc1OlpMediaObjectsBB(PMHW_BATCH_BUFFER batchBuffer)148 MOS_STATUS CodechalDecodeVc1G8::AddVc1OlpMediaObjectsBB(
149 PMHW_BATCH_BUFFER batchBuffer)
150 {
151 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
152
153 CODECHAL_DECODE_FUNCTION_ENTER;
154
155 CODECHAL_DECODE_CHK_NULL_RETURN(m_hwInterface->GetRenderInterface());
156
157 uint16_t surfaceWidthInBlock = m_olpPicWidthInMb;
158 uint16_t surfaceHeightInBlock = m_olpPicHeightInMb;
159
160 CODECHAL_DECODE_VC1_OLP_INLINE_DATA_G8 inlineData = g_cInit_CODECHAL_DECODE_VC1_OLP_INLINE_DATA_G8;
161
162 MHW_MEDIA_OBJECT_PARAMS mediaObjectParams;
163 MOS_ZeroMemory(&mediaObjectParams, sizeof(mediaObjectParams));
164 mediaObjectParams.dwInterfaceDescriptorOffset = m_olpKernelState.dwIdOffset;
165 mediaObjectParams.dwInlineDataSize = sizeof(CODECHAL_DECODE_VC1_OLP_INLINE_DATA_G8);
166 mediaObjectParams.pInlineData = &inlineData;
167
168 // Process each Block (16x16) for Y surface
169 inlineData.DW1.ComponentFlag = 0;
170 inlineData.DW2.DestDataBindingIndex = 3;
171 inlineData.DW2.SourceDataBindingIndex = 0;
172
173 uint32_t tileX = 0, tileY = 0;
174 for (tileY = 0; tileY < surfaceHeightInBlock; tileY++)
175 {
176 for (tileX = 0; tileX < surfaceWidthInBlock; tileX++)
177 {
178 inlineData.DW0.BlockOriginX = tileX * 16;
179 inlineData.DW0.BlockOriginY = tileY * 16;
180
181 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetRenderInterface()->AddMediaObject(nullptr, batchBuffer, &mediaObjectParams));
182 }
183 }
184
185 surfaceHeightInBlock = MOS_ALIGN_CEIL(m_olpPicHeightInMb, 2) / 2;
186 inlineData.DW1.ComponentFlag = 1;
187 inlineData.DW2.DestDataBindingIndex = 4;
188 inlineData.DW2.SourceDataBindingIndex = 1;
189
190 for (tileY = 0; tileY < surfaceHeightInBlock; tileY++)
191 {
192 for (tileX = 0; tileX < surfaceWidthInBlock; tileX++)
193 {
194 inlineData.DW0.BlockOriginX = tileX * 16;
195 inlineData.DW0.BlockOriginY = tileY * 16;
196 mediaObjectParams.pInlineData = &inlineData;
197
198 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetRenderInterface()->AddMediaObject(nullptr, batchBuffer, &mediaObjectParams));
199 }
200 }
201
202 return eStatus;
203 }
204
UpdateVc1KernelState()205 MOS_STATUS CodechalDecodeVc1G8::UpdateVc1KernelState()
206 {
207 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
208
209 CODECHAL_DECODE_FUNCTION_ENTER;
210
211 PMHW_STATE_HEAP_INTERFACE stateHeapInterface = m_hwInterface->GetRenderInterface()->m_stateHeapInterface;
212 PCODECHAL_DECODE_VC1_KERNEL_HEADER decodeKernel;
213 PMHW_KERNEL_STATE kernelState = &m_olpKernelState;
214
215 decodeKernel = (PCODECHAL_DECODE_VC1_KERNEL_HEADER)kernelState->KernelParams.pBinary;
216 kernelState->dwKernelBinaryOffset =
217 decodeKernel->OLP.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT;
218 kernelState->KernelParams.iInlineDataLength = sizeof(CODECHAL_DECODE_VC1_OLP_INLINE_DATA_G8);
219
220 m_olpDshSize =
221 stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData() +
222 MOS_ALIGN_CEIL(m_olpCurbeStaticDataLength, stateHeapInterface->pStateHeapInterface->GetCurbeAlignment());
223
224 return eStatus;
225 }
226
AllocateResources()227 MOS_STATUS CodechalDecodeVc1G8::AllocateResources()
228 {
229 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
230
231 CODECHAL_DECODE_FUNCTION_ENTER;
232
233 CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeVc1::AllocateResources());
234
235 // Second level batch buffer for OLP
236 {
237 MOS_ZeroMemory(&m_olpBatchBuffer, sizeof(m_olpBatchBuffer));
238 uint32_t u32Size = m_hwInterface->GetMediaObjectBufferSize(
239 (m_numMacroblocks + m_numMacroblocksUv),
240 sizeof(CODECHAL_DECODE_VC1_OLP_INLINE_DATA_G8));
241 CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_AllocateBb(
242 m_osInterface,
243 &m_olpBatchBuffer,
244 nullptr,
245 u32Size));
246 m_olpBatchBuffer.bSecondLevel = true;
247 }
248
249 return eStatus;
250 }
251
AddVc1OlpCmd(PCODECHAL_DECODE_VC1_OLP_PARAMS vc1OlpParams)252 MOS_STATUS CodechalDecodeVc1G8::AddVc1OlpCmd(
253 PCODECHAL_DECODE_VC1_OLP_PARAMS vc1OlpParams)
254 {
255 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
256
257 CODECHAL_DECODE_FUNCTION_ENTER;
258
259 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(vc1OlpParams->pCmdBuffer, &m_olpBatchBuffer));
260
261 // check if we need to reset the batch buffer
262 if ((m_picWidthInMb - m_olpPicWidthInMb) ||
263 (m_picHeightInMb - m_olpPicHeightInMb))
264 {
265 CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_LockBb(m_osInterface, &m_olpBatchBuffer));
266 m_olpPicWidthInMb = m_picWidthInMb;
267 m_olpPicHeightInMb = m_picHeightInMb;
268
269 CODECHAL_DECODE_CHK_STATUS_RETURN(AddVc1OlpMediaObjectsBB(
270 &m_olpBatchBuffer));
271
272 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(nullptr, &m_olpBatchBuffer));
273
274 CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_UnlockBb(m_osInterface, &m_olpBatchBuffer, true));
275 }
276
277 CODECHAL_DEBUG_TOOL(
278 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch(
279 &m_olpBatchBuffer,
280 CODECHAL_MEDIA_STATE_OLP,
281 "_DEC"));)
282
283 return eStatus;
284 }
285
CodechalDecodeVc1G8(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)286 CodechalDecodeVc1G8::CodechalDecodeVc1G8(
287 CodechalHwInterface *hwInterface,
288 CodechalDebugInterface* debugInterface,
289 PCODECHAL_STANDARD_INFO standardInfo) :
290 CodechalDecodeVc1(hwInterface, debugInterface, standardInfo)
291 {
292 MOS_ZeroMemory(&m_olpBatchBuffer, sizeof(m_olpBatchBuffer));
293
294 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(hwInterface);
295
296 m_olpCurbeStaticDataLength = CODECHAL_DECODE_VC1_CURBE_SIZE_OLP_G8;
297
298 MOS_STATUS eStatus = CodecHalGetKernelBinaryAndSize(
299 (uint8_t *)IGCODECKRN_G8,
300 IDR_CODEC_AllVC1_NV12,
301 &m_olpKernelBase,
302 &m_olpKernelSize);
303
304 CODECHAL_DECODE_ASSERT(eStatus == MOS_STATUS_SUCCESS);
305
306 hwInterface->GetStateHeapSettings()->dwNumSyncTags = CODECHAL_DECODE_VC1_NUM_SYNC_TAGS;
307 hwInterface->GetStateHeapSettings()->dwIshSize =
308 MOS_ALIGN_CEIL(m_olpKernelSize, (1 << MHW_KERNEL_OFFSET_SHIFT));
309 hwInterface->GetStateHeapSettings()->dwDshSize = CODECHAL_DECODE_VC1_INITIAL_DSH_SIZE;
310 }
311
~CodechalDecodeVc1G8()312 CodechalDecodeVc1G8::~CodechalDecodeVc1G8()
313 {
314 Mhw_FreeBb(m_osInterface, &m_olpBatchBuffer, nullptr);
315 };
316