1 /*
2 * Copyright (c) 2017-2020, 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_utilities.cpp
24 //! \brief Implements the common functions for codec.
25 //! \details This modules implements utilities which are shared by encoder and decoder
26 //!
27
28 #include "codechal_hw.h"
29 #include "codeckrnheader.h"
30 #include "codechal_utilities.h"
31
CodecHalInitMediaObjectWalkerParams(CodechalHwInterface * hwInterface,PMHW_WALKER_PARAMS walkerParams,PCODECHAL_WALKER_CODEC_PARAMS walkerCodecParams)32 MOS_STATUS CodecHalInitMediaObjectWalkerParams(
33 CodechalHwInterface *hwInterface,
34 PMHW_WALKER_PARAMS walkerParams,
35 PCODECHAL_WALKER_CODEC_PARAMS walkerCodecParams)
36 {
37 CODECHAL_PUBLIC_CHK_NULL_RETURN(hwInterface);
38 CODECHAL_PUBLIC_CHK_NULL_RETURN(walkerParams);
39 CODECHAL_PUBLIC_CHK_NULL_RETURN(walkerCodecParams);
40
41 MOS_ZeroMemory(walkerParams, sizeof(MHW_WALKER_PARAMS));
42
43 walkerParams->WalkerMode =
44 (MHW_WALKER_MODE)walkerCodecParams->WalkerMode;
45 walkerParams->UseScoreboard = walkerCodecParams->bUseScoreboard;
46
47 walkerParams->BlockResolution.x = walkerCodecParams->dwResolutionX;
48 walkerParams->BlockResolution.y = walkerCodecParams->dwResolutionY;
49
50 walkerParams->GlobalResolution.x = walkerCodecParams->dwResolutionX;
51 walkerParams->GlobalResolution.y = walkerCodecParams->dwResolutionY;
52
53 walkerParams->GlobalOutlerLoopStride.x = walkerCodecParams->dwResolutionX;
54 walkerParams->GlobalOutlerLoopStride.y = 0;
55
56 walkerParams->GlobalInnerLoopUnit.x = 0;
57 walkerParams->GlobalInnerLoopUnit.y = walkerCodecParams->dwResolutionY;
58
59 // Gen7.5 & Gen8: 0x3FF, Gen9: 0x7FF
60 walkerParams->dwLocalLoopExecCount = 0xFFFF; //MAX VALUE
61 walkerParams->dwGlobalLoopExecCount = 0xFFFF; //MAX VALUE
62
63 if (walkerCodecParams->bMbEncIFrameDistInUse || walkerCodecParams->bNoDependency)
64 {
65 walkerParams->ScoreboardMask = 0;
66 // Raster scan walking pattern
67 walkerParams->LocalOutLoopStride.x = 0;
68 walkerParams->LocalOutLoopStride.y = 1;
69 walkerParams->LocalInnerLoopUnit.x = 1;
70 walkerParams->LocalInnerLoopUnit.y = 0;
71 walkerParams->LocalEnd.x = walkerCodecParams->dwResolutionX - 1;
72 walkerParams->LocalEnd.y = 0;
73 }
74 else if (walkerCodecParams->bUseVerticalRasterScan)
75 {
76 walkerParams->ScoreboardMask = 0x1;
77 walkerParams->LocalOutLoopStride.x = 1;
78 walkerParams->LocalOutLoopStride.y = 0;
79 walkerParams->LocalInnerLoopUnit.x = 0;
80 walkerParams->LocalInnerLoopUnit.y = 1;
81 walkerParams->LocalEnd.x = 0;
82 walkerParams->LocalEnd.y = walkerCodecParams->dwResolutionY - 1;
83 }
84 else
85 {
86 walkerParams->LocalEnd.x = 0;
87 walkerParams->LocalEnd.y = 0;
88
89 if (walkerCodecParams->WalkerDegree == CODECHAL_46_DEGREE) // Gen6 only VP8 HybridPak2Pattern
90 {
91 // 46 degree walking pattern
92 walkerParams->ScoreboardMask = walkerCodecParams->ScoreboardMask;
93 walkerParams->LocalOutLoopStride.x = 1;
94 walkerParams->LocalOutLoopStride.y = 0;
95 walkerParams->LocalInnerLoopUnit.x = 0x3FF; // -1
96 walkerParams->LocalInnerLoopUnit.y = 1;
97 }
98 else if (walkerCodecParams->WalkerDegree == CODECHAL_45Z_DEGREE)
99 {
100 // 45z degree pattern
101 walkerParams->ScoreboardMask = 0x0F;
102
103 walkerParams->dwGlobalLoopExecCount = 0x3FF;
104 walkerParams->dwLocalLoopExecCount = 0x3FF;
105
106 walkerParams->GlobalResolution.x = uint32_t(walkerCodecParams->dwResolutionX / 2.f) + 1;
107 walkerParams->GlobalResolution.y = 2 * walkerCodecParams->dwResolutionY;
108
109 walkerParams->GlobalStart.x = 0;
110 walkerParams->GlobalStart.y = 0;
111
112 walkerParams->GlobalOutlerLoopStride.x = walkerParams->GlobalResolution.x;
113 walkerParams->GlobalOutlerLoopStride.y = 0;
114
115 walkerParams->GlobalInnerLoopUnit.x = 0;
116 walkerParams->GlobalInnerLoopUnit.y = walkerParams->GlobalResolution.y;
117
118 walkerParams->BlockResolution.x = walkerParams->GlobalResolution.x;
119 walkerParams->BlockResolution.y = walkerParams->GlobalResolution.y;
120
121 walkerParams->LocalStart.x = 0;
122 walkerParams->LocalStart.y = 0;
123
124 walkerParams->LocalOutLoopStride.x = 1;
125 walkerParams->LocalOutLoopStride.y = 0;
126
127 walkerParams->LocalInnerLoopUnit.x = MOS_BITFIELD_VALUE((uint32_t)-1, 16);
128 walkerParams->LocalInnerLoopUnit.y = 4;
129
130 walkerParams->MiddleLoopExtraSteps = 3;
131 walkerParams->MidLoopUnitX = 0;
132 walkerParams->MidLoopUnitY = 1;
133 }
134 else if ( walkerCodecParams->WalkerDegree == CODECHAL_45_DEGREE || // Gen8,9
135 ( ( walkerCodecParams->wPictureCodingType == I_TYPE || (walkerCodecParams->wPictureCodingType == B_TYPE && !walkerCodecParams->bDirectSpatialMVPredFlag) ) // CHECK B_TYPE ALWAYS
136 && walkerCodecParams->WalkerDegree != CODECHAL_26_DEGREE ) )
137 {
138 // 45 degree walking pattern
139 walkerParams->ScoreboardMask = 0x03;
140 walkerParams->LocalOutLoopStride.x = 1;
141 walkerParams->LocalOutLoopStride.y = 0;
142 walkerParams->LocalInnerLoopUnit.x = MOS_BITFIELD_VALUE((uint32_t)-1, 16); // Gen9: 0xFFF Gen6,8: 0x3FF
143 walkerParams->LocalInnerLoopUnit.y = 1;
144 }
145 else if ( walkerCodecParams->WalkerDegree == CODECHAL_26Z_DEGREE )
146 {
147 // 26z degree walking pattern used for HEVC
148 walkerParams->ScoreboardMask = 0x7f;
149
150 // z-order in the local loop
151 walkerParams->LocalOutLoopStride.x = 0;
152 walkerParams->LocalOutLoopStride.y = 1;
153 walkerParams->LocalInnerLoopUnit.x = 1;
154 walkerParams->LocalInnerLoopUnit.y = 0;
155
156 // dispatch 4 threads together in one LCU
157 walkerParams->BlockResolution.x = 2;
158 walkerParams->BlockResolution.y = 2;
159
160 // 26 degree in the global loop
161 walkerParams->GlobalOutlerLoopStride.x = 2;
162 walkerParams->GlobalOutlerLoopStride.y = 0;
163
164 walkerParams->GlobalInnerLoopUnit.x = 0xFFF -4 + 1; // -4 in 2's compliment format
165 walkerParams->GlobalInnerLoopUnit.y = 2;
166 }
167 else
168 {
169 // 26 degree walking pattern
170 walkerParams->ScoreboardMask = 0x0F;
171 walkerParams->LocalOutLoopStride.x = 1;
172 walkerParams->LocalOutLoopStride.y = 0;
173 walkerParams->LocalInnerLoopUnit.x = MOS_BITFIELD_VALUE((uint32_t)-2, 16); // Gen9: 0xFFE Gen6,8: 0x3FE
174 walkerParams->LocalInnerLoopUnit.y = 1;
175 }
176 }
177
178 if (walkerCodecParams->bMbaff)
179 {
180 walkerParams->ScoreboardMask = 0xFF;
181 walkerParams->MiddleLoopExtraSteps = 1;
182 walkerParams->MidLoopUnitY = 1;
183 walkerParams->LocalInnerLoopUnit.y = 2;
184 }
185
186 // In case of multiple Slice scenarios, every slice can be processed parallelly
187 // to enhance the performance. This is accomplished by launching the slices concurrently,
188 // providing the X and Y position of the thread along with Color bit. The AVC MBEnc kernel
189 // uses the color bit sent in the header to identify the Slice and calculates the MBY index
190 // accordingly.The color bit literally conveys the slice number of the MB.
191 if (walkerCodecParams->bColorbitSupported && walkerCodecParams->dwNumSlices <= CODECHAL_MEDIA_WALKER_MAX_COLORS)
192 {
193 walkerParams->ColorCountMinusOne = walkerCodecParams->dwNumSlices - 1;
194 walkerParams->BlockResolution.y = walkerCodecParams->usSliceHeight;
195 walkerParams->GlobalResolution.y = walkerCodecParams->usSliceHeight;
196 walkerParams->GlobalInnerLoopUnit.y = walkerCodecParams->usSliceHeight;
197 }
198
199 if(walkerCodecParams->bGroupIdSelectSupported)
200 {
201 walkerParams->GroupIdLoopSelect = walkerCodecParams->ucGroupId;
202 }
203
204 return MOS_STATUS_SUCCESS;
205 }
206
CodecHalGetKernelBinaryAndSize(uint8_t * kernelBase,uint32_t kernelUID,uint8_t ** kernelBinary,uint32_t * size)207 MOS_STATUS CodecHalGetKernelBinaryAndSize(
208 uint8_t* kernelBase,
209 uint32_t kernelUID,
210 uint8_t** kernelBinary,
211 uint32_t* size)
212 {
213 #ifdef ENABLE_KERNELS
214
215 CODECHAL_PUBLIC_CHK_NULL_RETURN(kernelBase);
216 CODECHAL_PUBLIC_CHK_NULL_RETURN(kernelBinary);
217 CODECHAL_PUBLIC_CHK_NULL_RETURN(size);
218
219 if (kernelUID >= IDR_CODEC_TOTAL_NUM_KERNELS)
220 {
221 return MOS_STATUS_INVALID_PARAMETER;
222 }
223
224 auto kernelOffsetTable = (uint32_t*)kernelBase;
225 auto binaryBase = (uint8_t*)(kernelOffsetTable + IDR_CODEC_TOTAL_NUM_KERNELS + 1);
226
227 *size = kernelOffsetTable[kernelUID + 1] - kernelOffsetTable[kernelUID];
228 *kernelBinary = (*size) > 0 ? binaryBase + kernelOffsetTable[kernelUID] : nullptr;
229 #else
230 *size = 0;
231 *kernelBinary = nullptr;
232 #endif
233
234 return MOS_STATUS_SUCCESS;
235 }
236
CodecHal_GetSurfaceWidthInBytes(PMOS_SURFACE surface,uint32_t * widthInBytes)237 void CodecHal_GetSurfaceWidthInBytes(
238 PMOS_SURFACE surface,
239 uint32_t *widthInBytes)
240 {
241 uint32_t width;
242
243 switch (surface->Format)
244 {
245 case Format_IMC1:
246 case Format_IMC3:
247 case Format_IMC2:
248 case Format_IMC4:
249 case Format_NV12:
250 case Format_YV12:
251 case Format_I420:
252 case Format_IYUV:
253 case Format_400P:
254 case Format_411P:
255 case Format_422H:
256 case Format_422V:
257 case Format_444P:
258 case Format_RGBP:
259 case Format_BGRP:
260 width = surface->dwWidth;
261 break;
262 case Format_YUY2:
263 case Format_YUYV:
264 case Format_YVYU:
265 case Format_UYVY:
266 case Format_VYUY:
267 case Format_P010:
268 width = surface->dwWidth << 1;
269 break;
270 case Format_Y210:
271 case Format_Y216:
272 case Format_A8R8G8B8:
273 case Format_X8R8G8B8:
274 case Format_A8B8G8R8:
275 case Format_R32U:
276 case Format_R32F:
277 width = surface->dwWidth << 2;
278 break;
279 default:
280 width = surface->dwWidth;
281 break;
282 }
283
284 *widthInBytes = width;
285 }
286
CodecHalSetRcsSurfaceState(CodechalHwInterface * hwInterface,PMOS_COMMAND_BUFFER cmdBuffer,PCODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams,PMHW_KERNEL_STATE kernelState)287 MOS_STATUS CodecHalSetRcsSurfaceState(
288 CodechalHwInterface *hwInterface,
289 PMOS_COMMAND_BUFFER cmdBuffer,
290 PCODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams,
291 PMHW_KERNEL_STATE kernelState)
292 {
293 CODECHAL_PUBLIC_CHK_NULL_RETURN(hwInterface);
294 CODECHAL_PUBLIC_CHK_NULL_RETURN(surfaceCodecParams);
295 CODECHAL_PUBLIC_CHK_NULL_RETURN(hwInterface->GetRenderInterface());
296 CODECHAL_PUBLIC_CHK_NULL_RETURN(hwInterface->GetRenderInterface()->m_stateHeapInterface);
297 CODECHAL_PUBLIC_CHK_NULL_RETURN(hwInterface->GetOsInterface());
298
299 PMHW_STATE_HEAP_INTERFACE stateHeapInterface = hwInterface->GetRenderInterface()->m_stateHeapInterface;
300 PMOS_INTERFACE osInterface = hwInterface->GetOsInterface();
301
302 MHW_RCS_SURFACE_PARAMS surfaceRcsParams;
303 MOS_ZeroMemory(&surfaceRcsParams, sizeof(MHW_RCS_SURFACE_PARAMS));
304
305 // default initial values
306 surfaceRcsParams.dwNumPlanes = 1; // MHW_GENERIC_PLANE = MHW_Y_PLANE
307 surfaceRcsParams.dwCacheabilityControl = surfaceCodecParams->dwCacheabilityControl;
308 surfaceRcsParams.bRenderTarget = surfaceCodecParams->bRenderTarget;
309 surfaceRcsParams.bIsWritable = surfaceCodecParams->bIsWritable;
310 surfaceRcsParams.dwBaseAddrOffset[MHW_Y_PLANE] = surfaceCodecParams->dwOffset;
311
312 uint32_t surfaceFormat;
313 MOS_SURFACE bufferSurface;
314 if (surfaceCodecParams->bIs2DSurface) // 2D
315 {
316 if (surfaceCodecParams->bUse32UnormSurfaceFormat)
317 {
318 surfaceFormat = MHW_GFX3DSTATE_SURFACEFORMAT_R32_UNORM;
319 }
320 else if (surfaceCodecParams->bUse16UnormSurfaceFormat)
321 {
322 surfaceFormat = MHW_GFX3DSTATE_SURFACEFORMAT_R16_UNORM;
323 }
324 else if (surfaceCodecParams->bUseARGB8Format)
325 {
326 // Ds+Copy kernel requires input surface set to ARGB8
327 surfaceFormat = MHW_GFX3DSTATE_SURFACEFORMAT_R8G8B8A8_UNORM;
328 }
329 else if (surfaceCodecParams->bUse32UINTSurfaceFormat)
330 {
331 surfaceFormat = MHW_GFX3DSTATE_SURFACEFORMAT_R32_UINT;
332 }
333 else if (surfaceCodecParams->psSurface->Format == Format_YUY2)
334 {
335 surfaceFormat = MHW_GFX3DSTATE_SURFACEFORMAT_YCRCB_NORMAL;
336 }
337 else if (surfaceCodecParams->psSurface->Format == Format_UYVY)
338 {
339 surfaceFormat = MHW_GFX3DSTATE_SURFACEFORMAT_YCRCB_SWAPY;
340 }
341 else if (surfaceCodecParams->psSurface->Format == Format_P010)
342 {
343 surfaceFormat = MHW_GFX3DSTATE_SURFACEFORMAT_R16_UNORM;
344 }
345 else //NV12
346 {
347 surfaceFormat = MHW_GFX3DSTATE_SURFACEFORMAT_R8_UNORM;
348 }
349
350 surfaceRcsParams.ForceSurfaceFormat[MHW_Y_PLANE] = surfaceFormat;
351 surfaceRcsParams.dwSurfaceType = GFX3DSTATE_SURFACETYPE_2D;
352 // MMC info passed with psSurface->CompressionMode
353 surfaceRcsParams.psSurface = surfaceCodecParams->psSurface;
354
355 uint32_t widthInBytes;
356 if( surfaceCodecParams->bMediaBlockRW )
357 {
358 CodecHal_GetSurfaceWidthInBytes(surfaceCodecParams->psSurface, &widthInBytes);
359 surfaceRcsParams.dwWidthToUse[MHW_Y_PLANE] = WIDTH_IN_DW(widthInBytes);
360 }
361 else
362 {
363 surfaceRcsParams.dwWidthToUse[MHW_Y_PLANE] = surfaceCodecParams->psSurface->dwWidth;
364 }
365
366 surfaceRcsParams.dwHeightToUse[MHW_Y_PLANE] = (surfaceCodecParams->dwHeightInUse == 0) ?
367 ((surfaceCodecParams->bUseHalfHeight) ? (surfaceCodecParams->psSurface->dwHeight / 2) : surfaceCodecParams->psSurface->dwHeight)
368 : surfaceCodecParams->dwHeightInUse;
369
370 if (surfaceCodecParams->bCheckCSC8Format &&
371 (surfaceCodecParams->psSurface->Format == Format_AYUV || surfaceCodecParams->psSurface->Format == Format_Y410 ||
372 surfaceCodecParams->psSurface->Format == Format_R10G10B10A2 || surfaceCodecParams->psSurface->Format == Format_B10G10R10A2))
373 {
374 surfaceRcsParams.ForceSurfaceFormat[MHW_Y_PLANE] = MHW_GFX3DSTATE_SURFACEFORMAT_R8_UNORM;
375 surfaceRcsParams.dwWidthToUse[MHW_Y_PLANE] = surfaceRcsParams.dwWidthToUse[MHW_Y_PLANE] * 4;
376 }
377
378 surfaceRcsParams.dwBindingTableOffset[MHW_Y_PLANE] = surfaceCodecParams->dwBindingTableOffset;
379 surfaceRcsParams.dwYOffset[MHW_Y_PLANE] = surfaceCodecParams->psSurface->YPlaneOffset.iYOffset;
380 surfaceRcsParams.bVertLineStride = surfaceCodecParams->dwVerticalLineStride;
381 surfaceRcsParams.bVertLineStrideOffs = surfaceCodecParams->dwVerticalLineStrideOffset;
382 surfaceRcsParams.psSurface->dwDepth = 1; // depth needs to be 0 for codec 2D surface
383
384 if (surfaceCodecParams->bUseUVPlane) // UV
385 {
386 surfaceRcsParams.dwNumPlanes = 2; // Y, UV
387 if (surfaceCodecParams->bForceChromaFormat)
388 {
389 surfaceRcsParams.ForceSurfaceFormat[MHW_U_PLANE] = surfaceCodecParams->ChromaType;
390 }
391 else
392 {
393 MOS_MEMCOMP_STATE mmcstate;
394
395 CODECHAL_PUBLIC_CHK_STATUS_RETURN(osInterface->pfnGetMemoryCompressionMode(
396 osInterface, &surfaceRcsParams.psSurface->OsResource, &mmcstate));
397
398 // MMC HW requires GFX3DSTATE_SURFACEFORMAT_YCRCB_SWAPUVY format for P010 UV planes.
399 surfaceRcsParams.ForceSurfaceFormat[MHW_U_PLANE] = (surfaceCodecParams->psSurface->Format == Format_P010) ?
400 ((mmcstate != MOS_MEMCOMP_DISABLED) ? MHW_GFX3DSTATE_SURFACEFORMAT_YCRCB_SWAPUVY : MHW_GFX3DSTATE_SURFACEFORMAT_R16G16_UNORM) :
401 MHW_GFX3DSTATE_SURFACEFORMAT_R16_UINT;
402 }
403 surfaceRcsParams.dwBindingTableOffset[MHW_U_PLANE] = surfaceCodecParams->dwUVBindingTableOffset;
404
405 widthInBytes = surfaceCodecParams->psSurface->dwWidth;
406 if (surfaceCodecParams->psSurface->Format == Format_P010)
407 {
408 widthInBytes *= 2;
409 }
410 surfaceRcsParams.dwWidthToUse[MHW_U_PLANE] = (surfaceCodecParams->bMediaBlockRW) ?
411 WIDTH_IN_DW(widthInBytes) : (surfaceCodecParams->psSurface->dwWidth / 2);
412 surfaceRcsParams.dwHeightToUse[MHW_U_PLANE] = (surfaceCodecParams->bUseHalfHeight) ?
413 (surfaceCodecParams->psSurface->dwHeight / 4) : (surfaceCodecParams->psSurface->dwHeight / 2);
414
415 if (surfaceCodecParams->psSurface->Format == Format_YUY2V || surfaceCodecParams->psSurface->Format == Format_Y216V || surfaceCodecParams->psSurface->Format == Format_P208)
416 {
417 surfaceRcsParams.dwHeightToUse[MHW_U_PLANE] = surfaceRcsParams.dwHeightToUse[MHW_U_PLANE] * 2;
418 }
419
420 if (IS_Y_MAJOR_TILE_FORMAT(surfaceRcsParams.psSurface->TileType))
421 {
422 uint32_t tileHeightAlignment =
423 (MOS_TILE_YS == surfaceRcsParams.psSurface->TileType) ? MOS_YSTILE_H_ALIGNMENT : MOS_YTILE_H_ALIGNMENT;
424
425 surfaceRcsParams.dwBaseAddrOffset[MHW_U_PLANE] =
426 surfaceCodecParams->psSurface->dwPitch *
427 MOS_ALIGN_FLOOR(surfaceCodecParams->psSurface->UPlaneOffset.iYOffset, tileHeightAlignment);
428 surfaceRcsParams.dwYOffset[MHW_U_PLANE] =
429 (surfaceCodecParams->psSurface->UPlaneOffset.iYOffset % tileHeightAlignment);
430 }
431 else if( MOS_TILE_LINEAR == surfaceRcsParams.psSurface->TileType )
432 {
433 surfaceRcsParams.dwBaseAddrOffset[MHW_U_PLANE] =
434 surfaceCodecParams->psSurface->dwPitch * surfaceCodecParams->psSurface->UPlaneOffset.iYOffset;
435 surfaceRcsParams.dwYOffset[MHW_U_PLANE] = 0;
436 }
437 else if( MOS_TILE_X == surfaceRcsParams.psSurface->TileType )
438 {
439 CODECHAL_PUBLIC_ASSERTMESSAGE("X_TILE surface not supported yet!");
440 return MOS_STATUS_INVALID_PARAMETER;
441 }
442 else
443 {
444 CODECHAL_PUBLIC_ASSERTMESSAGE("Invalid surface TileType");
445 return MOS_STATUS_INVALID_PARAMETER;
446 }
447 }
448
449 if (surfaceCodecParams->bUseHalfHeight)
450 {
451 surfaceRcsParams.MediaBoundaryPixelMode = GFX3DSTATE_BOUNDARY_INTERLACED_FRAME;
452 }
453 }
454 else if (surfaceCodecParams->bUseAdvState) // AdvState
455 {
456 surfaceRcsParams.bUseAdvState = surfaceCodecParams->bUseAdvState;
457 // MMC info passed with psSurface->CompressionMode
458 surfaceRcsParams.psSurface = surfaceCodecParams->psSurface;
459 surfaceRcsParams.dwWidthToUse[MHW_Y_PLANE] = surfaceCodecParams->dwWidthInUse;
460 surfaceRcsParams.dwWidthToUse[MHW_U_PLANE] = surfaceRcsParams.dwWidthToUse[MHW_V_PLANE] = surfaceCodecParams->dwWidthInUse / 2;
461 surfaceRcsParams.dwHeightToUse[MHW_Y_PLANE] = surfaceCodecParams->dwHeightInUse;
462 surfaceRcsParams.dwHeightToUse[MHW_U_PLANE] = surfaceRcsParams.dwHeightToUse[MHW_V_PLANE] =
463 (surfaceCodecParams->psSurface->Format == Format_YUY2V || surfaceCodecParams->psSurface->Format == Format_Y216V) ?
464 surfaceCodecParams->dwHeightInUse :
465 surfaceCodecParams->dwHeightInUse / 2;
466
467 surfaceRcsParams.ForceSurfaceFormat[MHW_Y_PLANE] = MHW_MEDIASTATE_SURFACEFORMAT_PLANAR_420_8;
468 surfaceRcsParams.dwBindingTableOffset[MHW_Y_PLANE] = surfaceCodecParams->dwBindingTableOffset;
469 surfaceRcsParams.bInterleaveChroma = true;
470 surfaceRcsParams.Direction = (MHW_CHROMA_SITING_VDIRECTION) surfaceCodecParams->ucVDirection;
471 surfaceRcsParams.dwYOffset[MHW_U_PLANE] = surfaceCodecParams->psSurface->UPlaneOffset.iYOffset;
472 }
473 else // 1D Buffer
474 {
475 MOS_ZeroMemory(&bufferSurface, sizeof(MOS_SURFACE));
476 MOS_SecureMemcpy(&bufferSurface.OsResource, sizeof(MOS_RESOURCE), surfaceCodecParams->presBuffer, sizeof(MOS_RESOURCE));
477
478 surfaceRcsParams.psSurface = &bufferSurface;
479
480 surfaceRcsParams.ForceSurfaceFormat[MHW_Y_PLANE] = surfaceCodecParams->bRawSurface ?
481 MHW_GFX3DSTATE_SURFACEFORMAT_RAW : MHW_GFX3DSTATE_SURFACEFORMAT_R32_UINT;
482 surfaceRcsParams.dwBindingTableOffset[MHW_Y_PLANE] = surfaceCodecParams->dwBindingTableOffset;
483
484 surfaceRcsParams.psSurface->Type = MOS_GFXRES_BUFFER;
485 surfaceRcsParams.psSurface->Format = Format_Buffer;
486 surfaceRcsParams.psSurface->TileType = MOS_TILE_LINEAR;
487 surfaceRcsParams.psSurface->dwSize = surfaceCodecParams->dwSize;
488 surfaceRcsParams.psSurface->dwWidth = (surfaceCodecParams->dwSize - 1) & 0x7F;
489 surfaceRcsParams.psSurface->dwHeight = ((surfaceCodecParams->dwSize - 1) & 0x1FFF80) >> 7;
490 surfaceRcsParams.psSurface->dwDepth = ((surfaceCodecParams->dwSize - 1) & 0xFE00000) >> 21;
491 // GMM doesn't provide pitch info from surface
492 surfaceRcsParams.psSurface->dwPitch = surfaceCodecParams->bRawSurface ? sizeof(uint8_t) : sizeof(uint32_t);
493 surfaceRcsParams.psSurface->bArraySpacing = true;
494 }
495
496 CODECHAL_PUBLIC_CHK_STATUS_RETURN(stateHeapInterface->pfnSetSurfaceState(
497 stateHeapInterface,
498 kernelState,
499 cmdBuffer,
500 1,
501 &surfaceRcsParams));
502
503 return MOS_STATUS_SUCCESS;
504 }
505
CodecHalGetResourceInfo(PMOS_INTERFACE osInterface,PMOS_SURFACE surface)506 MOS_STATUS CodecHalGetResourceInfo(
507 PMOS_INTERFACE osInterface,
508 PMOS_SURFACE surface)
509 {
510 CODECHAL_PUBLIC_CHK_NULL_RETURN(surface);
511
512 MOS_SURFACE details;
513 MOS_ZeroMemory(&details, sizeof(details));
514 details.Format = Format_Invalid;
515
516 CODECHAL_PUBLIC_CHK_STATUS_RETURN(osInterface->pfnGetResourceInfo(osInterface, &surface->OsResource, &details));
517
518 surface->Format = details.Format;
519 surface->dwWidth = details.dwWidth;
520 surface->dwHeight = details.dwHeight;
521 surface->dwPitch = details.dwPitch;
522 surface->dwDepth = details.dwDepth;
523 surface->dwQPitch = details.dwQPitch;
524 surface->bArraySpacing = details.bArraySpacing;
525 surface->TileType = details.TileType;
526 surface->TileModeGMM = details.TileModeGMM;
527 surface->bGMMTileEnabled = details.bGMMTileEnabled;
528 surface->dwOffset = details.RenderOffset.YUV.Y.BaseOffset;
529 surface->YPlaneOffset.iSurfaceOffset = details.RenderOffset.YUV.Y.BaseOffset;
530 surface->YPlaneOffset.iXOffset = details.RenderOffset.YUV.Y.XOffset;
531 surface->YPlaneOffset.iYOffset =
532 (surface->YPlaneOffset.iSurfaceOffset - surface->dwOffset) / surface->dwPitch +
533 details.RenderOffset.YUV.Y.YOffset;
534 surface->UPlaneOffset.iSurfaceOffset = details.RenderOffset.YUV.U.BaseOffset;
535 surface->UPlaneOffset.iXOffset = details.RenderOffset.YUV.U.XOffset;
536 surface->UPlaneOffset.iYOffset =
537 (surface->UPlaneOffset.iSurfaceOffset - surface->dwOffset) / surface->dwPitch +
538 details.RenderOffset.YUV.U.YOffset;
539 surface->UPlaneOffset.iLockSurfaceOffset = details.LockOffset.YUV.U;
540 surface->VPlaneOffset.iSurfaceOffset = details.RenderOffset.YUV.V.BaseOffset;
541 surface->VPlaneOffset.iXOffset = details.RenderOffset.YUV.V.XOffset;
542 surface->VPlaneOffset.iYOffset =
543 (surface->VPlaneOffset.iSurfaceOffset - surface->dwOffset) / surface->dwPitch +
544 details.RenderOffset.YUV.V.YOffset;
545 surface->VPlaneOffset.iLockSurfaceOffset = details.LockOffset.YUV.V;
546 surface->bCompressible = details.bCompressible;
547 surface->CompressionMode = details.CompressionMode;
548 surface->bIsCompressed = details.bIsCompressed;
549
550 return MOS_STATUS_SUCCESS;
551 }
552