1 /*
2 * Copyright (c) 2021-2023, 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 #include "vp_utils.h"
24 #include "vp_common.h"
25 #include "hal_kerneldll_next.h"
26 #include "mos_interface.h"
27
ReAllocateSurface(PMOS_INTERFACE osInterface,PVPHAL_SURFACE surface,PCCHAR surfaceName,MOS_FORMAT format,MOS_GFXRES_TYPE defaultResType,MOS_TILE_TYPE defaultTileType,uint32_t dwWidth,uint32_t dwHeight,bool bCompressible,MOS_RESOURCE_MMC_MODE compressionMode,bool * bAllocated,MOS_HW_RESOURCE_DEF resUsageType,MOS_TILE_MODE_GMM tileModeByForce,Mos_MemPool memType,bool isNotLockable)28 MOS_STATUS VpUtils::ReAllocateSurface(
29 PMOS_INTERFACE osInterface,
30 PVPHAL_SURFACE surface,
31 PCCHAR surfaceName,
32 MOS_FORMAT format,
33 MOS_GFXRES_TYPE defaultResType,
34 MOS_TILE_TYPE defaultTileType,
35 uint32_t dwWidth,
36 uint32_t dwHeight,
37 bool bCompressible,
38 MOS_RESOURCE_MMC_MODE compressionMode,
39 bool *bAllocated,
40 MOS_HW_RESOURCE_DEF resUsageType,
41 MOS_TILE_MODE_GMM tileModeByForce,
42 Mos_MemPool memType,
43 bool isNotLockable)
44 {
45 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
46 VPHAL_GET_SURFACE_INFO info = {};
47 MOS_ALLOC_GFXRES_PARAMS allocParams = {};
48 MOS_GFXRES_FREE_FLAGS resFreeFlags = {0};
49
50 //---------------------------------
51 VP_PUBLIC_ASSERT(osInterface);
52 VP_PUBLIC_ASSERT(surface);
53 //---------------------------------
54
55 *bAllocated = false;
56
57 // bCompressible should be compared with bCompressible since it is inited by bCompressible in previous call
58 // TileType of surface should be compared since we need to reallocate surface if TileType changes
59 if (!Mos_ResourceIsNull(&surface->OsResource) &&
60 (surface->dwWidth == dwWidth) &&
61 (surface->dwHeight == dwHeight) &&
62 (surface->Format == format) &&
63 (surface->bCompressible == bCompressible) &&
64 (surface->CompressionMode == compressionMode) &&
65 (surface->TileType == defaultTileType))
66 {
67 goto finish;
68 }
69
70 // reuse the allocated buffer if the allocated size was larger than request size when OptimizeCpuTiming is enabled
71 if (osInterface->bOptimizeCpuTiming &&
72 !Mos_ResourceIsNull(&surface->OsResource) &&
73 (Format_Buffer == format) &&
74 (surface->dwWidth * surface->dwHeight >= dwWidth * dwHeight))
75 {
76 goto finish;
77 }
78
79 MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
80
81 VpHal_AllocParamsInitType(&allocParams, surface, defaultResType, defaultTileType);
82
83 allocParams.dwWidth = dwWidth;
84 allocParams.dwHeight = dwHeight;
85 allocParams.Format = format;
86 allocParams.bIsCompressible = bCompressible;
87 allocParams.CompressionMode = compressionMode;
88 allocParams.pBufName = surfaceName;
89 allocParams.dwArraySize = 1;
90 allocParams.ResUsageType = resUsageType;
91 allocParams.m_tileModeByForce = tileModeByForce;
92 allocParams.dwMemType = memType;
93 allocParams.Flags.bNotLockable = isNotLockable;
94
95 // Delete resource if already allocated
96 //if free the compressed surface, need set the sync dealloc flag as 1 for sync dealloc for aux table update
97 if (IsSyncFreeNeededForMMCSurface(surface, osInterface))
98 {
99 resFreeFlags.SynchronousDestroy = 1;
100 VP_PUBLIC_NORMALMESSAGE("Set SynchronousDestroy flag for compressed resource %s", surfaceName);
101 }
102 osInterface->pfnFreeResourceWithFlag(osInterface, &(surface->OsResource), resFreeFlags.Value);
103
104 // Allocate surface
105 VP_PUBLIC_CHK_STATUS(osInterface->pfnAllocateResource(
106 osInterface,
107 &allocParams,
108 &surface->OsResource));
109
110 // Get surface information
111 MOS_ZeroMemory(&info, sizeof(VPHAL_GET_SURFACE_INFO));
112
113 // Pre-set to get surface info
114 surface->Format = format;
115
116 VP_PUBLIC_CHK_STATUS(VpHal_GetSurfaceInfo(osInterface, &info, surface));
117
118 *bAllocated = true;
119
120 MT_LOG7(MT_VP_HAL_REALLOC_SURF, MT_NORMAL, MT_VP_HAL_INTER_SURF_TYPE, surfaceName ? *((int64_t *)surfaceName) : 0, MT_SURF_WIDTH, dwWidth, MT_SURF_HEIGHT, dwHeight, MT_SURF_MOS_FORMAT, format, MT_SURF_TILE_MODE, surface->TileModeGMM, MT_SURF_COMP_ABLE, surface->bCompressible, MT_SURF_COMP_MODE, surface->CompressionMode);
121
122 finish:
123 VP_PUBLIC_ASSERT(eStatus == MOS_STATUS_SUCCESS);
124 return eStatus;
125 }
126
IsVerticalRotation(VPHAL_ROTATION rotation)127 bool VpUtils::IsVerticalRotation(VPHAL_ROTATION rotation) {
128 return (rotation != VPHAL_ROTATION_IDENTITY &&
129 rotation != VPHAL_ROTATION_180 &&
130 rotation != VPHAL_MIRROR_VERTICAL &&
131 rotation != VPHAL_MIRROR_HORIZONTAL);
132 }
133
IsSyncFreeNeededForMMCSurface(PVPHAL_SURFACE surface,PMOS_INTERFACE osInterface)134 bool VpUtils::IsSyncFreeNeededForMMCSurface(PVPHAL_SURFACE surface, PMOS_INTERFACE osInterface)
135 {
136 if (nullptr == surface || nullptr == osInterface)
137 {
138 return false;
139 }
140
141 //Compressed surface aux table update is after resource dealloction, aux table update need wait the WLs complete
142 //the sync deallocation flag will make sure deallocation API return after all surface related WL been completed and resource been destroyed by OS
143 auto *pSkuTable = osInterface->pfnGetSkuTable(osInterface);
144 if (pSkuTable &&
145 MEDIA_IS_SKU(pSkuTable, FtrE2ECompression) && //Compression enabled platform
146 !MEDIA_IS_SKU(pSkuTable, FtrFlatPhysCCS) && //NOT DGPU compression
147 ((surface->bCompressible) && (surface->CompressionMode != MOS_MMC_DISABLED))) //Compressed enabled surface
148 {
149 return true;
150 }
151
152 return false;
153 }
154
GetCscMatrixForVeSfc8Bit(VPHAL_CSPACE srcCspace,VPHAL_CSPACE dstCspace,float * fCscCoeff,float * fCscInOffset,float * fCscOutOffset)155 void VpUtils::GetCscMatrixForVeSfc8Bit(
156 VPHAL_CSPACE srcCspace,
157 VPHAL_CSPACE dstCspace,
158 float *fCscCoeff,
159 float *fCscInOffset,
160 float *fCscOutOffset)
161 {
162 float fCscMatrix[12] = {0};
163 int32_t i = 0;
164
165 KernelDll_GetCSCMatrix(
166 srcCspace,
167 dstCspace,
168 fCscMatrix);
169
170 // Copy [3x3] into Coeff
171 for (i = 0; i < 3; i++)
172 {
173 MOS_SecureMemcpy(
174 &fCscCoeff[i * 3],
175 sizeof(float) * 3,
176 &fCscMatrix[i * 4],
177 sizeof(float) * 3);
178 }
179
180 // Get the input offsets
181 switch (srcCspace)
182 {
183 CASE_YUV_CSPACE_LIMITEDRANGE:
184 fCscInOffset[0] = -16.0F;
185 fCscInOffset[1] = -128.0F;
186 fCscInOffset[2] = -128.0F;
187 break;
188
189 CASE_YUV_CSPACE_FULLRANGE:
190 fCscInOffset[0] = 0.0F;
191 fCscInOffset[1] = -128.0F;
192 fCscInOffset[2] = -128.0F;
193 break;
194
195 case CSpace_sRGB:
196 fCscInOffset[0] = 0.0F;
197 fCscInOffset[1] = 0.0F;
198 fCscInOffset[2] = 0.0F;
199 break;
200
201 case CSpace_stRGB:
202 fCscInOffset[0] = -16.0F;
203 fCscInOffset[1] = -16.0F;
204 fCscInOffset[2] = -16.0F;
205 break;
206
207 //BT2020 YUV->RGB
208 case CSpace_BT2020:
209 fCscInOffset[0] = -16.0F;
210 fCscInOffset[1] = -128.0F;
211 fCscInOffset[2] = -128.0F;
212 break;
213
214 case CSpace_BT2020_FullRange:
215 fCscInOffset[0] = 0.0F;
216 fCscInOffset[1] = -128.0F;
217 fCscInOffset[2] = -128.0F;
218 break;
219
220 //BT2020 RGB->YUV
221 case CSpace_BT2020_RGB:
222 fCscInOffset[0] = 0.0F;
223 fCscInOffset[1] = 0.0F;
224 fCscInOffset[2] = 0.0F;
225 break;
226
227 //BT2020 RGB->YUV
228 case CSpace_BT2020_stRGB:
229 fCscInOffset[0] = -16.0F;
230 fCscInOffset[1] = -16.0F;
231 fCscInOffset[2] = -16.0F;
232 break;
233
234 default:
235 VP_PUBLIC_NORMALMESSAGE("Unsupported Input ColorSpace for Vebox %d.", (uint32_t)srcCspace);
236 }
237
238 // Get the output offsets
239 switch (dstCspace)
240 {
241 CASE_YUV_CSPACE_LIMITEDRANGE:
242 fCscOutOffset[0] = 16.0F;
243 fCscOutOffset[1] = 128.0F;
244 fCscOutOffset[2] = 128.0F;
245 break;
246
247 CASE_YUV_CSPACE_FULLRANGE:
248 fCscOutOffset[0] = 0.0F;
249 fCscOutOffset[1] = 128.0F;
250 fCscOutOffset[2] = 128.0F;
251 break;
252
253 case CSpace_sRGB:
254 fCscOutOffset[0] = 0.0F;
255 fCscOutOffset[1] = 0.0F;
256 fCscOutOffset[2] = 0.0F;
257 break;
258
259 case CSpace_stRGB:
260 fCscOutOffset[0] = 16.0F;
261 fCscOutOffset[1] = 16.0F;
262 fCscOutOffset[2] = 16.0F;
263 break;
264
265 //BT2020 RGB->YUV
266 case CSpace_BT2020:
267 fCscOutOffset[0] = 16.0F;
268 fCscOutOffset[1] = 128.0F;
269 fCscOutOffset[2] = 128.0F;
270 break;
271
272 case CSpace_BT2020_FullRange:
273 fCscOutOffset[0] = 0.0F;
274 fCscOutOffset[1] = 128.0F;
275 fCscOutOffset[2] = 128.0F;
276 break;
277
278 case CSpace_BT2020_RGB:
279 fCscOutOffset[0] = 0.0F;
280 fCscOutOffset[1] = 0.0F;
281 fCscOutOffset[2] = 0.0F;
282 break;
283
284 case CSpace_BT2020_stRGB:
285 fCscOutOffset[0] = 16.0F;
286 fCscOutOffset[1] = 16.0F;
287 fCscOutOffset[2] = 16.0F;
288 break;
289
290 default:
291 VP_PUBLIC_NORMALMESSAGE("Unsupported Output ColorSpace for Vebox %d.", (uint32_t)dstCspace);
292 }
293 }
294
GetCscMatrixForRender8Bit(VPHAL_COLOR_SAMPLE_8 * output,VPHAL_COLOR_SAMPLE_8 * input,VPHAL_CSPACE srcCspace,VPHAL_CSPACE dstCspace)295 bool VpUtils::GetCscMatrixForRender8Bit(
296 VPHAL_COLOR_SAMPLE_8 *output,
297 VPHAL_COLOR_SAMPLE_8 *input,
298 VPHAL_CSPACE srcCspace,
299 VPHAL_CSPACE dstCspace)
300 {
301 float pfCscMatrix[12] = {0};
302 int32_t iCscMatrix[12] = {0};
303 bool bResult = false;
304 int32_t i = 0;
305
306 KernelDll_GetCSCMatrix(srcCspace, dstCspace, pfCscMatrix);
307
308 // convert float to fixed point format for the 3x4 matrix
309 for (i = 0; i < 12; i++)
310 {
311 // multiply by 2^20 and round up
312 iCscMatrix[i] = (int32_t)((pfCscMatrix[i] * 1048576.0f) + 0.5f);
313 }
314
315 bResult = GetCscMatrixForRender8BitWithCoeff(output, input, srcCspace, dstCspace, iCscMatrix);
316
317 return bResult;
318 }
319
GetCscMatrixForRender8BitWithCoeff(VPHAL_COLOR_SAMPLE_8 * output,VPHAL_COLOR_SAMPLE_8 * input,VPHAL_CSPACE srcCspace,VPHAL_CSPACE dstCspace,int32_t * iCscMatrix)320 bool VpUtils::GetCscMatrixForRender8BitWithCoeff(
321 VPHAL_COLOR_SAMPLE_8 *output,
322 VPHAL_COLOR_SAMPLE_8 *input,
323 VPHAL_CSPACE srcCspace,
324 VPHAL_CSPACE dstCspace,
325 int32_t *iCscMatrix)
326 {
327 bool bResult = true;
328 int32_t a = 0, r = 0, g = 0, b = 0;
329 int32_t y1 = 0, u1 = 0, v1 = 0;
330
331 y1 = r = input->YY;
332 u1 = g = input->Cb;
333 v1 = b = input->Cr;
334 a = input->Alpha;
335
336 if (srcCspace == dstCspace)
337 {
338 // no conversion needed
339 if ((dstCspace == CSpace_sRGB) || (dstCspace == CSpace_stRGB) || IS_COLOR_SPACE_BT2020_RGB(dstCspace))
340 {
341 output->A = (uint8_t)a;
342 output->R = (uint8_t)r;
343 output->G = (uint8_t)g;
344 output->B = (uint8_t)b;
345 }
346 else
347 {
348 output->a = (uint8_t)a;
349 output->Y = (uint8_t)y1;
350 output->U = (uint8_t)u1;
351 output->V = (uint8_t)v1;
352 }
353 }
354 else
355 {
356 // conversion needed
357 r = (y1 * iCscMatrix[0] + u1 * iCscMatrix[1] +
358 v1 * iCscMatrix[2] + iCscMatrix[3] + 0x00080000) >>
359 20;
360 g = (y1 * iCscMatrix[4] + u1 * iCscMatrix[5] +
361 v1 * iCscMatrix[6] + iCscMatrix[7] + 0x00080000) >>
362 20;
363 b = (y1 * iCscMatrix[8] + u1 * iCscMatrix[9] +
364 v1 * iCscMatrix[10] + iCscMatrix[11] + 0x00080000) >>
365 20;
366
367 switch (dstCspace)
368 {
369 case CSpace_sRGB:
370 output->A = (uint8_t)a;
371 output->R = MOS_MIN(MOS_MAX(0, r), 255);
372 output->G = MOS_MIN(MOS_MAX(0, g), 255);
373 output->B = MOS_MIN(MOS_MAX(0, b), 255);
374 break;
375
376 case CSpace_stRGB:
377 output->A = (uint8_t)a;
378 output->R = MOS_MIN(MOS_MAX(16, r), 235);
379 output->G = MOS_MIN(MOS_MAX(16, g), 235);
380 output->B = MOS_MIN(MOS_MAX(16, b), 235);
381 break;
382
383 case CSpace_BT601:
384 case CSpace_BT709:
385 output->a = (uint8_t)a;
386 output->Y = MOS_MIN(MOS_MAX(16, r), 235);
387 output->U = MOS_MIN(MOS_MAX(16, g), 240);
388 output->V = MOS_MIN(MOS_MAX(16, b), 240);
389 break;
390
391 case CSpace_xvYCC601:
392 case CSpace_xvYCC709:
393 case CSpace_BT601_FullRange:
394 case CSpace_BT709_FullRange:
395 output->a = (uint8_t)a;
396 output->Y = MOS_MIN(MOS_MAX(0, r), 255);
397 output->U = MOS_MIN(MOS_MAX(0, g), 255);
398 output->V = MOS_MIN(MOS_MAX(0, b), 255);
399 break;
400
401 default:
402 VP_PUBLIC_NORMALMESSAGE("Unsupported Output ColorSpace %d.", (uint32_t)dstCspace);
403 bResult = false;
404 break;
405 }
406 }
407
408 return bResult;
409 }
410