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