1 /*
2 * Copyright (c) 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     media_blt_copy_xe_xpm_base.cpp
24 //! \brief    Common interface used in Blitter Engine
25 //! \details  Common interface used in Blitter Engine which are platform independent
26 //!
27 
28 #include "media_blt_copy_xe_xpm_base.h"
29 #include "mhw_cp_interface.h"
30 #include "media_interfaces_xehp_sdv.h"
31 #include "mos_os_specific_next.h"
32 
33 //!
34 //! \brief    BltStateXe_Xpm constructor
35 //! \details  Initialize the BltStateXe_Xpm members.
36 //! \param    osInterface
37 //!           [in] Pointer to MOS_INTERFACE.
38 //!
BltStateXe_Xpm(PMOS_INTERFACE osInterface)39 BltStateXe_Xpm::BltStateXe_Xpm(PMOS_INTERFACE    osInterface) :
40     BltState(osInterface),
41     initialized(false),
42     allocated(false),
43     tempSurface(nullptr),
44     tempAuxSurface(nullptr),
45     surfaceSize(0),
46     auxSize(0),
47     pMainSurface(nullptr),
48     pAuxSurface(nullptr)
49 {
50 
51 }
52 
53 //!
54 //! \brief    BltStateXe_Xpm constructor
55 //! \details  Initialize the BltStateXe_Xpm members.
56 //! \param    osInterface
57 //!           [in] Pointer to MOS_INTERFACE.
58 //!
BltStateXe_Xpm(PMOS_INTERFACE osInterface,MhwInterfaces * mhwInterfaces)59 BltStateXe_Xpm::BltStateXe_Xpm(PMOS_INTERFACE    osInterface, MhwInterfaces *mhwInterfaces) :
60     BltState(osInterface, mhwInterfaces),
61     initialized(false),
62     allocated(false),
63     tempSurface(nullptr),
64     tempAuxSurface(nullptr),
65     surfaceSize(0),
66     auxSize(0),
67     pMainSurface(nullptr),
68     pAuxSurface(nullptr)
69 {
70 
71 }
72 
73 
~BltStateXe_Xpm()74 BltStateXe_Xpm::~BltStateXe_Xpm()
75 {
76     FreeResource();
77     if (pMainSurface)
78     {
79         MOS_FreeMemAndSetNull(pMainSurface);
80     }
81     if (pAuxSurface)
82     {
83         MOS_FreeMemAndSetNull(pAuxSurface);
84     }
85 }
86 
87 //!
88 //! \brief    BltStateXe_Xpm initialize
89 //! \details  Initialize the BltStateXe_Xpm, create BLT context.
90 //! \return   MOS_STATUS
91 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
92 //!
Initialize()93 MOS_STATUS BltStateXe_Xpm::Initialize()
94 {
95     BLT_CHK_STATUS_RETURN(BltState::Initialize());
96     initialized = true;
97 
98     return MOS_STATUS_SUCCESS;
99 }
100 
101 //!
102 //! \brief    InitProtectResource
103 //! \details  Init target resource
104 //! \param    target
105 //!           [in] Pointer to tartget resource
106 //! \return   MOS_STATUS
107 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
108 //!
InitProtectResource(PMOS_RESOURCE target)109 MOS_STATUS BltStateXe_Xpm::InitProtectResource(PMOS_RESOURCE target)
110 {
111     BLT_CHK_NULL_RETURN(target);
112     BLT_CHK_NULL_RETURN(m_osInterface);
113 
114     if (!allocated)
115     {
116         tempSurface = (PMOS_SURFACE)MOS_AllocAndZeroMemory(sizeof(MOS_SURFACE));
117         BLT_CHK_NULL_RETURN(tempSurface);
118 
119         MOS_ALLOC_GFXRES_PARAMS AllocParams;
120         MOS_ZeroMemory(&AllocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
121         AllocParams.Type = MOS_GFXRES_2D;
122         AllocParams.TileType = MapTileType(target->pGmmResInfo->GetResFlags(), target->pGmmResInfo->GetTileType());
123         AllocParams.Format = ConvertFormatGmmToMos(target->pGmmResInfo->GetResourceFormat());
124         AllocParams.dwWidth = (uint32_t)target->pGmmResInfo->GetBaseWidth();
125         AllocParams.dwHeight = (uint32_t)target->pGmmResInfo->GetBaseHeight();
126 
127         BLT_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
128             m_osInterface, &AllocParams, &tempSurface->OsResource));
129         allocated = true;
130     }
131 
132     BLT_CHK_STATUS_RETURN(CopyProtectResource(&tempSurface->OsResource, target));
133 
134     return MOS_STATUS_SUCCESS;
135 }
136 
137 //!
138 //! \brief    CopyProtectResource
139 //! \param    src
140 //!           [in] Pointer to source resource
141 //! \param    dst
142 //!           [out] Pointer to destination resource
143 //! \return   MOS_STATUS
144 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
145 //!
CopyProtectResource(PMOS_RESOURCE src,PMOS_RESOURCE dst)146 MOS_STATUS BltStateXe_Xpm::CopyProtectResource(
147     PMOS_RESOURCE src,
148     PMOS_RESOURCE dst)
149 {
150     BLT_CHK_NULL_RETURN(src);
151     BLT_CHK_NULL_RETURN(dst);
152     BLT_CHK_NULL_RETURN(m_osInterface);
153 
154     MOS_MEMCOMP_STATE mmcState;
155     BLT_CHK_STATUS_RETURN(m_osInterface->pfnGetMemoryCompressionMode(m_osInterface, dst, &mmcState));
156 
157     BLT_CHK_STATUS_RETURN(m_osInterface->pfnDoubleBufferCopyResource(
158         m_osInterface,
159         src,
160         dst,
161         ((mmcState == MOS_MEMCOMP_MC) || (mmcState == MOS_MEMCOMP_RC)) ? true : false));
162 
163     return MOS_STATUS_SUCCESS;
164 }
165 
166 //!
167 //! \brief    CopyProtectSurface
168 //! \param    src
169 //!           [in] Pointer to source surface
170 //! \param    dst
171 //!           [in] Pointer to destination buffer
172 //! \return   MOS_STATUS
173 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
174 //!
CopyProtectSurface(PMOS_SURFACE src,PMOS_SURFACE dst)175 MOS_STATUS BltStateXe_Xpm::CopyProtectSurface(
176     PMOS_SURFACE src,
177     PMOS_SURFACE dst)
178 {
179     BLT_CHK_NULL_RETURN(src);
180     BLT_CHK_NULL_RETURN(dst);
181     BLT_CHK_NULL_RETURN(m_miInterface);
182     BLT_CHK_NULL_RETURN(m_cpInterface);
183 
184     MOS_GPUCTX_CREATOPTIONS createOption;
185     BLT_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
186         m_osInterface,
187         MOS_GPU_CONTEXT_VIDEO,
188         MOS_GPU_NODE_VIDEO,
189         &createOption));
190 
191     BLT_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, MOS_GPU_CONTEXT_VIDEO));
192 
193     MHW_ADD_CP_COPY_PARAMS cpCopyParams;
194     MOS_ZeroMemory(&cpCopyParams, sizeof(cpCopyParams));
195     cpCopyParams.size    = src->dwWidth * src->dwHeight;
196     cpCopyParams.presSrc = &src->OsResource;
197     cpCopyParams.presDst = &dst->OsResource;
198     cpCopyParams.offset  = 0;
199     MOS_COMMAND_BUFFER cmdBuffer;
200     BLT_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
201 
202     // add CP prolog
203     BLT_CHK_STATUS_RETURN(m_miInterface->AddProtectedProlog(&cmdBuffer));
204 
205     BLT_CHK_STATUS_RETURN(m_cpInterface->AddCpCopy(m_osInterface, &cmdBuffer, &cpCopyParams));
206 
207     //MI flush cmd
208     MHW_MI_FLUSH_DW_PARAMS FlushDwParams;
209     MOS_ZeroMemory(&FlushDwParams, sizeof(FlushDwParams));
210     BLT_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
211         &cmdBuffer,
212         &FlushDwParams));
213 
214     //BatchBuffer end
215     BLT_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
216 
217     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
218     // Flush the command buffer
219     BLT_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, false));
220 
221     return MOS_STATUS_SUCCESS;
222 }
223 
224 //!
225 //! \brief    ConvertFormatGmmToMos
226 //! \param    format
227 //!           [in] GMM format (GMM_FORMAT_*)
228 //! \return   MOS_FORMAT
229 //!           Return MOS_FORMAT corresponding to GMM format or Format_Invalid if no mapping
230 //!
ConvertFormatGmmToMos(GMM_RESOURCE_FORMAT format)231 MOS_FORMAT BltStateXe_Xpm::ConvertFormatGmmToMos(GMM_RESOURCE_FORMAT format)
232 {
233     switch (format)
234     {
235         case GMM_FORMAT_B8G8R8A8_UNORM_TYPE:        return Format_A8R8G8B8;
236         case GMM_FORMAT_B8G8R8X8_UNORM_TYPE:        return Format_X8R8G8B8;
237         case GMM_FORMAT_R8G8B8A8_UNORM_TYPE:        return Format_A8B8G8R8;
238         case GMM_FORMAT_B5G6R5_UNORM_TYPE:          return Format_R5G6B5;
239         case GMM_FORMAT_R8G8B8_UNORM:               return Format_R8G8B8;
240         case GMM_FORMAT_R32_UINT_TYPE:              return Format_R32U;
241         case GMM_FORMAT_R32_FLOAT_TYPE:             return Format_R32F;
242         case GMM_FORMAT_MEDIA_Y8_UNORM:             return Format_Y8;
243         case GMM_FORMAT_MEDIA_Y1_UNORM:             return Format_Y8;
244         case GMM_FORMAT_MEDIA_Y16_UNORM:            return Format_Y16U;
245         case GMM_FORMAT_MEDIA_Y16_SNORM:            return Format_Y16S;
246         case GMM_FORMAT_YUY2_2x1:                   return Format_YUY2;
247         case GMM_FORMAT_YUY2:                       return Format_YUY2;
248         case GMM_FORMAT_P8:                         return Format_P8;
249         case GMM_FORMAT_R16_UNORM_TYPE:             return Format_R16UN;
250         case GMM_FORMAT_A8_UNORM_TYPE:              return Format_A8;
251         case GMM_FORMAT_GENERIC_8BIT:               return Format_L8;
252         case GMM_FORMAT_L16_UNORM_TYPE:             return Format_L16;
253         case GMM_FORMAT_GENERIC_16BIT_TYPE:         return Format_D16;
254         case GMM_FORMAT_YVYU:                       return Format_YVYU;
255         case GMM_FORMAT_UYVY:                       return Format_UYVY;
256         case GMM_FORMAT_VYUY_2x1:                   return Format_VYUY;
257         case GMM_FORMAT_VYUY:                       return Format_VYUY;
258         case GMM_FORMAT_P016_TYPE:                  return Format_P016;
259         case GMM_FORMAT_P010_TYPE:                  return Format_P010;
260         case GMM_FORMAT_NV12_TYPE:                  return Format_NV12;
261         case GMM_FORMAT_NV11_TYPE:                  return Format_NV11;
262         case GMM_FORMAT_P208_TYPE:                  return Format_P208;
263         case GMM_FORMAT_IMC1_TYPE:                  return Format_IMC1;
264         case GMM_FORMAT_IMC2_TYPE:                  return Format_IMC2;
265         case GMM_FORMAT_IMC3_TYPE:                  return Format_IMC3;
266         case GMM_FORMAT_IMC4_TYPE:                  return Format_IMC4;
267         case GMM_FORMAT_I420_TYPE:                  return Format_I420;
268         case GMM_FORMAT_IYUV_TYPE:                  return Format_IYUV;
269         case GMM_FORMAT_YV12_TYPE:                  return Format_YV12;
270         case GMM_FORMAT_YVU9_TYPE:                  return Format_YVU9;
271         case GMM_FORMAT_R8_UNORM_TYPE:              return Format_R8UN;
272         case GMM_FORMAT_R16_UINT_TYPE:              return Format_R16U;
273         case GMM_FORMAT_R8G8_SNORM:                 return Format_V8U8;
274         case GMM_FORMAT_R8_UINT_TYPE:               return Format_R8U;
275         case GMM_FORMAT_R32_SINT:                   return Format_R32S;
276         case GMM_FORMAT_R8G8_UNORM_TYPE:            return Format_R8G8UN;
277         case GMM_FORMAT_R16_SINT_TYPE:              return Format_R16S;
278         case GMM_FORMAT_R16G16B16A16_UNORM_TYPE:    return Format_A16B16G16R16;
279         case GMM_FORMAT_R16G16B16A16_FLOAT_TYPE:    return Format_A16B16G16R16F;
280         case GMM_FORMAT_R10G10B10A2_UNORM_TYPE:     return Format_R10G10B10A2;
281         case GMM_FORMAT_MFX_JPEG_YUV422H_TYPE:      return Format_422H;
282         case GMM_FORMAT_MFX_JPEG_YUV411_TYPE:       return Format_411P;
283         case GMM_FORMAT_MFX_JPEG_YUV422V_TYPE:      return Format_422V;
284         case GMM_FORMAT_MFX_JPEG_YUV444_TYPE:       return Format_444P;
285         case GMM_FORMAT_BAYER_BGGR16:               return Format_IRW0;
286         case GMM_FORMAT_BAYER_RGGB16:               return Format_IRW1;
287         case GMM_FORMAT_BAYER_GRBG16:               return Format_IRW2;
288         case GMM_FORMAT_BAYER_GBRG16:               return Format_IRW3;
289         case GMM_FORMAT_R8G8B8A8_UINT_TYPE:         return Format_AYUV;
290         case GMM_FORMAT_AYUV:                       return Format_AYUV;
291         case GMM_FORMAT_R16G16_UNORM_TYPE:          return Format_R16G16UN;
292         case GMM_FORMAT_R16_FLOAT:                  return Format_R16F;
293         case GMM_FORMAT_Y416_TYPE:                  return Format_Y416;
294         case GMM_FORMAT_Y410_TYPE:                  return Format_Y410;
295         case GMM_FORMAT_Y210_TYPE:                  return Format_Y210;
296         case GMM_FORMAT_Y216_TYPE:                  return Format_Y216;
297         case GMM_FORMAT_MFX_JPEG_YUV411R_TYPE:      return Format_411R;
298         case GMM_FORMAT_RGBP_TYPE:                  return Format_RGBP;
299         case GMM_FORMAT_BGRP_TYPE:                  return Format_RGBP;
300         case GMM_FORMAT_R24_UNORM_X8_TYPELESS:      return Format_D24S8UN;
301         case GMM_FORMAT_R32_FLOAT_X8X24_TYPELESS:   return Format_D32S8X24_FLOAT;
302         case GMM_FORMAT_R16G16_SINT_TYPE:           return Format_R16G16S;
303         case GMM_FORMAT_R32G32B32A32_FLOAT:         return Format_R32G32B32A32F;
304         default:                                    return Format_Invalid;
305     }
306 }
307 
308 
309 //!
310 //! \brief    MapTileType
311 //! \param    flags
312 //!           [in] GMM resource flags
313 //! \param    type
314 //!           [in] GMM tile type
315 //! \return   MOS_TILE_TYPE
316 //!           Return MOS tile type for given GMM resource and tile flags
317 //!
MapTileType(GMM_RESOURCE_FLAG flags,GMM_TILE_TYPE type)318 MOS_TILE_TYPE BltStateXe_Xpm::MapTileType(GMM_RESOURCE_FLAG flags, GMM_TILE_TYPE type)
319 {
320     switch (type)
321     {
322         case GMM_TILED_Y:
323             if (flags.Info.TiledYf)
324             {
325                 return MOS_TILE_YF;
326             }
327             else if (flags.Info.TiledYs)
328             {
329                 return MOS_TILE_YS;
330             }
331             else
332             {
333                 return MOS_TILE_Y;
334             }
335             break;
336         case GMM_TILED_X:
337             return MOS_TILE_X;
338             break;
339         case GMM_TILED_4:
340         case GMM_TILED_64:
341             return MOS_TILE_Y;
342             break;
343         case GMM_NOT_TILED:
344         default:
345             return MOS_TILE_LINEAR;
346             break;
347     }
348 }
349 
350 
351 //!
352 //! \brief    Get control surface
353 //! \details  BLT engine will copy aux data of source surface to destination
354 //! \param    src
355 //!           [in] Pointer to source surface
356 //! \param    dst
357 //!           [in] Pointer to destination buffer is created for aux data
358 //! \return   MOS_STATUS
359 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
360 //!
GetCCS(PMOS_SURFACE src,PMOS_SURFACE dst)361 MOS_STATUS BltStateXe_Xpm::GetCCS(
362     PMOS_SURFACE src,
363     PMOS_SURFACE dst)
364 {
365     BLT_STATE_XE_XPM_BASE_PARAM bltStateParam;
366 
367     BLT_CHK_NULL_RETURN(src);
368     BLT_CHK_NULL_RETURN(dst);
369     BLT_CHK_NULL_RETURN(&src->OsResource);
370     BLT_CHK_NULL_RETURN(&dst->OsResource);
371 
372     MOS_ZeroMemory(&bltStateParam, sizeof(BLT_STATE_XE_XPM_BASE_PARAM));
373     bltStateParam.bCopyCCS = true;
374     bltStateParam.ccsFlag  = CCS_READ;
375     bltStateParam.pSrcCCS  = src;
376     bltStateParam.pDstCCS  = dst;
377 
378     BLT_CHK_STATUS_RETURN(SubmitCMD(&bltStateParam));
379 
380     // sync
381     MOS_LOCK_PARAMS flag;
382     flag.Value     = 0;
383     flag.WriteOnly = 1;
384     BLT_CHK_STATUS_RETURN(m_osInterface->pfnLockSyncRequest(m_osInterface, &dst->OsResource, &flag));
385 
386     return MOS_STATUS_SUCCESS;
387 }
388 
389 //!
390 //! \brief    Put control surface
391 //! \details  BLT engine will copy aux data of source surface to destination
392 //! \param    src
393 //!           [in] Pointer to source surface
394 //! \param    dst
395 //!           [in] Pointer to destination buffer is created for aux data
396 //! \return   MOS_STATUS
397 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
398 //!
PutCCS(PMOS_SURFACE src,PMOS_SURFACE dst)399 MOS_STATUS BltStateXe_Xpm::PutCCS(
400     PMOS_SURFACE src,
401     PMOS_SURFACE dst)
402 {
403     BLT_STATE_XE_XPM_BASE_PARAM bltStateParam;
404 
405     BLT_CHK_NULL_RETURN(src);
406     BLT_CHK_NULL_RETURN(dst);
407     BLT_CHK_NULL_RETURN(&src->OsResource);
408     BLT_CHK_NULL_RETURN(&dst->OsResource);
409 
410     MOS_ZeroMemory(&bltStateParam, sizeof(BLT_STATE_XE_XPM_BASE_PARAM));
411     bltStateParam.bCopyCCS = true;
412     bltStateParam.ccsFlag  = CCS_WRITE;
413     bltStateParam.pSrcCCS  = src;
414     bltStateParam.pDstCCS  = dst;
415 
416     BLT_CHK_STATUS_RETURN(SubmitCMD(&bltStateParam));
417 
418     // sync
419     MOS_LOCK_PARAMS flag;
420     flag.Value     = 0;
421     flag.WriteOnly = 1;
422     BLT_CHK_STATUS_RETURN(m_osInterface->pfnLockSyncRequest(m_osInterface, &dst->OsResource, &flag));
423 
424     return MOS_STATUS_SUCCESS;
425 }
426 
427 //!
428 //! \brief    Lock surface
429 //! \details  Lock surface to get main surface and aux data
430 //! \param    pSrcSurface
431 //!           [in] Pointer to source surface
432 //! \return   MOS_STATUS
433 //!           MOS_STATUS_SUCCESS if success, otherwise error code
434 //!
LockSurface(PMOS_SURFACE pSurface)435 MOS_STATUS BltStateXe_Xpm::LockSurface(
436     PMOS_SURFACE pSurface)
437 {
438     MOS_STATUS eStatus    = MOS_STATUS_SUCCESS;
439     void*      pTemp      = nullptr;
440 
441     BLT_CHK_NULL(pSurface);
442 
443     // Initialize for the first time
444     if (!initialized)
445     {
446         BLT_CHK_STATUS(Initialize());
447     }
448 
449     // Allocate internel resource
450     BLT_CHK_STATUS(AllocateResource(pSurface));
451 
452     // Get main surface and CCS
453     // Currentlt main surface copy will cause page fault, which cause crash.
454     // BLT_CHK_STATUS(CopyMainSurface(pSurface, tempSurface));
455     BLT_CHK_STATUS(GetCCS(pSurface, tempAuxSurface));
456 
457     MOS_LOCK_PARAMS LockFlags;
458     LockFlags.Value        = 0;
459     LockFlags.ReadOnly     = 1;
460     LockFlags.TiledAsTiled = 1;
461     LockFlags.NoDecompress = 1;
462 
463     // Lock main surface data
464     pTemp = (uint8_t*)m_osInterface->pfnLockResource(
465         m_osInterface,
466         &pSurface->OsResource,
467         &LockFlags);
468     BLT_CHK_NULL(pTemp);
469 
470     MOS_SecureMemcpy(
471         pMainSurface,
472         surfaceSize,
473         pTemp,
474         surfaceSize);
475     BLT_CHK_STATUS(m_osInterface->pfnUnlockResource(m_osInterface, &pSurface->OsResource));
476 
477     // Lock CCS data
478     pTemp = (uint8_t*)m_osInterface->pfnLockResource(
479         m_osInterface,
480         &tempAuxSurface->OsResource,
481         &LockFlags);
482     BLT_CHK_NULL(pTemp);
483 
484     MOS_SecureMemcpy(
485         pAuxSurface,
486         auxSize,
487         pTemp,
488         auxSize);
489     BLT_CHK_STATUS(m_osInterface->pfnUnlockResource(m_osInterface, &tempAuxSurface->OsResource));
490 
491     return eStatus;
492 
493 finish:
494     BLT_ASSERTMESSAGE("BLT: Lock surface failed.");
495     FreeResource();
496     return eStatus;
497 }
498 
499 //!
500 //! \brief    Unlock surface
501 //! \details  Free resource created by lockSurface, must be called once call LockSurface
502 //! \return   MOS_STATUS
503 //!           MOS_STATUS_SUCCESS if success, otherwise error code
504 //!
UnLockSurface()505 MOS_STATUS BltStateXe_Xpm::UnLockSurface()
506 {
507     FreeResource();
508     return MOS_STATUS_SUCCESS;
509 }
510 
511 //!
512 //! \brief    Write compressed surface
513 //! \details  Write compressed surface data from system memory to GPU memory
514 //! \param    pSysMemory
515 //!           [in] Pointer to system memory
516 //! \param    dataSize
517 //!           [in] data size, including main surface data and aux data
518 //! \param    pSurface
519 //!           [in] Pointer to the destination surface
520 //! \return   MOS_STATUS
521 //!           MOS_STATUS_SUCCESS if success, otherwise error code
522 //!
WriteCompressedSurface(void * pSysMemory,uint32_t dataSize,PMOS_SURFACE pSurface)523 MOS_STATUS BltStateXe_Xpm::WriteCompressedSurface(
524     void*        pSysMemory,
525     uint32_t     dataSize,
526     PMOS_SURFACE pSurface)
527 {
528     MOS_STATUS eStatus  = MOS_STATUS_SUCCESS;
529     void*      pTemp    = nullptr;
530     uint32_t   sizeAux  = 0;
531     BLT_CHK_NULL(pSurface);
532 
533     // Initialize for the first time
534     if (!initialized)
535     {
536         BLT_CHK_STATUS(Initialize());
537     }
538 
539     // Allocate internel resource
540     BLT_CHK_STATUS(AllocateResource(pSurface));
541 
542     sizeAux = dataSize / 257;
543 
544     MOS_LOCK_PARAMS LockFlags;
545     LockFlags.Value     = 0;
546     LockFlags.WriteOnly = 1;
547     LockFlags.TiledAsTiled = 1;
548     LockFlags.NoDecompress = 1;
549 
550     // Lock temp main surface
551     pTemp = (uint32_t*)m_osInterface->pfnLockResource(
552         m_osInterface,
553         &pSurface->OsResource,
554         &LockFlags);
555     // copy surface data to temp surface
556     MOS_SecureMemcpy(
557         pTemp,
558         sizeAux*256,
559         pSysMemory,
560         sizeAux*256);
561     BLT_CHK_STATUS(m_osInterface->pfnUnlockResource(m_osInterface, &pSurface->OsResource));
562 
563     // Lock temp aux surface
564     pTemp = (uint8_t*)m_osInterface->pfnLockResource(
565         m_osInterface,
566         &tempAuxSurface->OsResource,
567         &LockFlags);
568     // copy aux data to temp aux surface
569     MOS_SecureMemcpy(
570         pTemp,
571         sizeAux,
572         (uint8_t*)pSysMemory+sizeAux*256,
573         sizeAux);
574     BLT_CHK_STATUS(m_osInterface->pfnUnlockResource(m_osInterface, &tempAuxSurface->OsResource));
575     BLT_CHK_STATUS_RETURN(PutCCS(tempAuxSurface, pSurface));
576 
577     FreeResource();
578     return eStatus;
579 
580 finish:
581     BLT_ASSERTMESSAGE("BLT: Write compressed surface failed.");
582     FreeResource();
583     return eStatus;
584 }
585 
586 //!
587 //! \brief    Allocate resource
588 //! \details  Allocate internel resource
589 //! \param    pSrcSurface
590 //!           [in] Pointer to source surface
591 //! \return   MOS_STATUS
592 //!           MOS_STATUS_SUCCESS if success, otherwise error code
593 //!
AllocateResource(PMOS_SURFACE pSurface)594 MOS_STATUS BltStateXe_Xpm::AllocateResource(
595     PMOS_SURFACE pSurface)
596 {
597     MOS_ALLOC_GFXRES_PARAMS AllocParams;
598 
599     tempSurface = (PMOS_SURFACE)MOS_AllocAndZeroMemory(sizeof(MOS_SURFACE));
600     tempAuxSurface     = (PMOS_SURFACE)MOS_AllocAndZeroMemory(sizeof(MOS_SURFACE));
601     BLT_CHK_NULL_RETURN(tempSurface);
602     BLT_CHK_NULL_RETURN(tempAuxSurface);
603 
604     // Always allocate the temp surface as compressible surface to make sure the size is correct.
605     MOS_ZeroMemory(&AllocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
606     AllocParams.TileType        = pSurface->TileType;
607     AllocParams.Type            = MOS_GFXRES_2D;
608     AllocParams.dwWidth         = pSurface->dwWidth;
609     AllocParams.dwHeight        = pSurface->dwHeight;
610     AllocParams.Format          = pSurface->Format;
611     AllocParams.bIsCompressible = true;
612     AllocParams.CompressionMode = pSurface->CompressionMode;
613     AllocParams.pBufName        = "TempOutSurface";
614     AllocParams.dwArraySize     = 1;
615 
616     BLT_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
617         m_osInterface,
618         &AllocParams,
619         &tempSurface->OsResource));
620 
621     tempSurface->dwPitch = pSurface->dwPitch;
622     tempSurface->dwWidth = pSurface->dwWidth;
623     tempSurface->dwHeight = pSurface->dwHeight;
624     tempSurface->Format   = pSurface->Format;
625     tempSurface->TileType = pSurface->TileType;
626 
627     MOS_ZeroMemory(&AllocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
628     AllocParams.TileType        = MOS_TILE_LINEAR;
629     AllocParams.Type            = MOS_GFXRES_BUFFER;
630     AllocParams.dwWidth         = (uint32_t)tempSurface->OsResource.pGmmResInfo->GetSizeMainSurface() / 256;
631     AllocParams.dwHeight        = 1;
632     AllocParams.Format          = Format_Buffer;
633     AllocParams.bIsCompressible = false;
634     AllocParams.CompressionMode = MOS_MMC_DISABLED;
635     AllocParams.pBufName        = "TempCCS";
636     AllocParams.dwArraySize     = 1;
637 
638     BLT_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
639         m_osInterface,
640         &AllocParams,
641         &tempAuxSurface->OsResource));
642 
643     surfaceSize  = (uint32_t)tempSurface->OsResource.pGmmResInfo->GetSizeMainSurface();
644     auxSize      = surfaceSize / 256;
645     pMainSurface = MOS_AllocAndZeroMemory(surfaceSize);
646     pAuxSurface  = MOS_AllocAndZeroMemory(auxSize);
647     BLT_CHK_NULL_RETURN(pMainSurface);
648     BLT_CHK_NULL_RETURN(pAuxSurface);
649 
650     allocated    = true;
651 
652     return MOS_STATUS_SUCCESS;
653 }
654 
655 //!
656 //! \brief    Free resource
657 //! \details  Free internel resource, must be called once call AllocateResource
658 //! \return   MOS_STATUS
659 //!           MOS_STATUS_SUCCESS if success, otherwise error code
660 //!
FreeResource()661 MOS_STATUS BltStateXe_Xpm::FreeResource()
662 {
663     if (allocated)
664     {
665         m_osInterface->pfnFreeResource(m_osInterface, &tempSurface->OsResource);
666         m_osInterface->pfnFreeResource(m_osInterface, &tempAuxSurface->OsResource);
667         allocated = false;
668     }
669     if (tempSurface)
670     {
671         MOS_FreeMemAndSetNull(tempSurface);
672     }
673     if (tempAuxSurface)
674     {
675         MOS_FreeMemAndSetNull(tempAuxSurface);
676     }
677 
678     return MOS_STATUS_SUCCESS;
679 }
680 
681 //!
682 //! \brief    Setup control surface copy parameters
683 //! \details  Setup control surface copy parameters for BLT Engine
684 //! \param    mhwParams
685 //!           [in/out] Pointer to MHW_CTRL_SURF_COPY_BLT_PARAM
686 //! \param    inputSurface
687 //!           [in] Pointer to input surface
688 //! \param    outputSurface
689 //!           [in] Pointer to output surface
690 //! \param    flag
691 //!           [in] Flag for read/write CCS
692 //! \return   MOS_STATUS
693 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
694 //!
SetupCtrlSurfCopyBltParam(PMHW_CTRL_SURF_COPY_BLT_PARAM pMhwBltParams,PMOS_SURFACE inputSurface,PMOS_SURFACE outputSurface,uint32_t flag)695 MOS_STATUS BltStateXe_Xpm::SetupCtrlSurfCopyBltParam(
696     PMHW_CTRL_SURF_COPY_BLT_PARAM pMhwBltParams,
697     PMOS_SURFACE                  inputSurface,
698     PMOS_SURFACE                  outputSurface,
699     uint32_t                      flag)
700 {
701     BLT_CHK_NULL_RETURN(pMhwBltParams);
702     BLT_CHK_NULL_RETURN(inputSurface);
703     BLT_CHK_NULL_RETURN(outputSurface);
704 
705     if (flag == CCS_READ)
706     {
707         pMhwBltParams->dwSrcMemoryType = 0;
708         pMhwBltParams->dwDstMemoryType = 1;
709         pMhwBltParams->dwSizeofControlSurface = (uint32_t)inputSurface->OsResource.pGmmResInfo->GetSizeMainSurface() / 65536;
710     }
711     else
712     {
713         pMhwBltParams->dwSrcMemoryType = 1;
714         pMhwBltParams->dwDstMemoryType = 0;
715         pMhwBltParams->dwSizeofControlSurface = (uint32_t)outputSurface->OsResource.pGmmResInfo->GetSizeMainSurface() / 65536;
716     }
717 
718     pMhwBltParams->pSrcOsResource  = &inputSurface->OsResource;
719     pMhwBltParams->pDstOsResource  = &outputSurface->OsResource;
720 
721     return MOS_STATUS_SUCCESS;
722 }
723 
724 //!
725 //! \brief    Submit command
726 //! \details  Submit BLT command
727 //! \param    pBltStateParam
728 //!           [in] Pointer to BLT_STATE_PARAM
729 //! \return   MOS_STATUS
730 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
731 //!
SubmitCMD(PBLT_STATE_XE_XPM_BASE_PARAM pBltStateParam)732 MOS_STATUS BltStateXe_Xpm::SubmitCMD(
733     PBLT_STATE_XE_XPM_BASE_PARAM pBltStateParam)
734 {
735     MOS_STATUS                   eStatus = MOS_STATUS_SUCCESS;
736     MOS_COMMAND_BUFFER           cmdBuffer;
737     MHW_FAST_COPY_BLT_PARAM      fastCopyBltParam;
738     MHW_CTRL_SURF_COPY_BLT_PARAM ctrlSurfCopyBltParam;
739     MOS_GPUCTX_CREATOPTIONS      createOption = {};
740     PMHW_BLT_INTERFACE_XE_HP     pbltInterface = dynamic_cast<PMHW_BLT_INTERFACE_XE_HP>(m_bltInterface);
741 
742     BLT_CHK_NULL(pbltInterface);
743 
744     // no gpucontext will be created if the gpu context has been created before.
745     BLT_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
746         m_osInterface,
747         MOS_GPU_CONTEXT_BLT,
748         MOS_GPU_NODE_BLT,
749         &createOption));
750     // Set GPU context
751     BLT_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(m_osInterface, MOS_GPU_CONTEXT_BLT));
752 
753     // Initialize the command buffer struct
754     MOS_ZeroMemory(&cmdBuffer, sizeof(MOS_COMMAND_BUFFER));
755     BLT_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
756 
757     if (pBltStateParam->bCopyMainSurface)
758     {
759         BLT_CHK_STATUS_RETURN(SetupFastCopyBltParam(
760             &fastCopyBltParam,
761             pBltStateParam->pSrcSurface,
762             pBltStateParam->pDstSurface));
763 
764         MHW_MI_LOAD_REGISTER_IMM_PARAMS RegisterDwParams;
765         MOS_ZeroMemory(&RegisterDwParams, sizeof(RegisterDwParams));
766         RegisterDwParams.dwRegister = mhw_blt_state::BCS_SWCTRL_CMD::REGISTER_OFFSET;
767 
768         mhw_blt_state_xe_hp_base::BCS_SWCTRL_CMD swctrl;
769         if (pBltStateParam->pSrcSurface->TileType != MOS_TILE_LINEAR)
770         {
771             swctrl.DW0.Tile4Source = 1;
772         }
773         if (pBltStateParam->pDstSurface->TileType != MOS_TILE_LINEAR)
774         {//output tiled
775             swctrl.DW0.Tile4Destination = 1;
776         }
777 
778         RegisterDwParams.dwData = swctrl.DW0.Value;
779         m_miInterface->AddMiLoadRegisterImmCmd(&cmdBuffer, &RegisterDwParams);
780 
781         BLT_CHK_STATUS_RETURN(m_bltInterface->AddFastCopyBlt(
782             &cmdBuffer,
783             &fastCopyBltParam));
784 
785     }
786 
787     if (pBltStateParam->bCopyCCS)
788     {
789         BLT_CHK_STATUS_RETURN(SetupCtrlSurfCopyBltParam(
790             &ctrlSurfCopyBltParam,
791             pBltStateParam->pSrcCCS,
792             pBltStateParam->pDstCCS,
793             pBltStateParam->ccsFlag));
794         BLT_CHK_STATUS_RETURN(pbltInterface->AddCtrlSurfCopyBlt(
795             &cmdBuffer,
796             &ctrlSurfCopyBltParam));
797     }
798 
799     // Add flush DW
800     MHW_MI_FLUSH_DW_PARAMS FlushDwParams;
801     MOS_ZeroMemory(&FlushDwParams, sizeof(FlushDwParams));
802     BLT_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &FlushDwParams));
803 
804     // Add Batch Buffer end
805     BLT_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
806 
807     // Flush the command buffer
808     BLT_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, false));
809 
810 finish:
811     return eStatus;
812 }
813 
CopyMainSurface(PMOS_RESOURCE src,PMOS_RESOURCE dst)814 MOS_STATUS BltStateXe_Xpm::CopyMainSurface(
815     PMOS_RESOURCE src,
816     PMOS_RESOURCE dst)
817 {
818     BLT_STATE_XE_XPM_BASE_PARAM bltStateParam;
819 
820     BLT_CHK_NULL_RETURN(src);
821     BLT_CHK_NULL_RETURN(dst);
822     MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
823 
824     MOS_ZeroMemory(&bltStateParam, sizeof(BLT_STATE_XE_XPM_BASE_PARAM));
825     bltStateParam.bCopyMainSurface = true;
826     bltStateParam.pSrcSurface      = src;
827     bltStateParam.pDstSurface      = dst;
828 
829     BLT_CHK_STATUS_RETURN(SubmitCMD(&bltStateParam));
830 
831     MOS_TraceEventExt(EVENT_MEDIA_COPY, EVENT_TYPE_END, nullptr, 0, nullptr, 0);
832     return MOS_STATUS_SUCCESS;
833 }