1 /*
2 * Copyright (c) 2017, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     CMRTKernel_I_16x16Sad.cpp
24 //! \brief    HEVC FEI I 16x16 SAD class for GEN9 SKL.
25 //!
26 
27 #include "CMRTKernel_I_16x16Sad.h"
28 #include "CMRTKernel_I_Kernel_def.h"
29 
CMRTKernelI16x16Sad()30 CMRTKernelI16x16Sad::CMRTKernelI16x16Sad()
31 {
32 
33     m_isaName          = HEVCENCFEI_I_GEN9;
34     m_isaSize          = HEVCENCFEI_I_GEN9_SIZE;
35     m_kernelName        = HEVCENCKERNELNAME_I_16x16SAD;
36 
37     m_cmSurface2DCount  = 3;
38     m_cmBufferCount     = 3;
39     m_cmVmeSurfCount    = 0;
40 
41     if (m_cmSurface2DCount > 0)
42     {
43         m_cmSurface2D     = (CmSurface2D **)malloc(sizeof(CmSurface2D *) * m_cmSurface2DCount);
44         if (m_cmSurface2D != nullptr)
45         {
46             memset(m_cmSurface2D, 0, sizeof(CmSurface2D *) * m_cmSurface2DCount);
47         }
48     }
49 
50     if (m_cmBufferCount > 0)
51     {
52         m_cmBuffer        = (CmBuffer **)malloc(sizeof(CmBuffer *) * m_cmBufferCount);
53         if (m_cmBuffer != nullptr)
54         {
55             memset(m_cmBuffer, 0, sizeof(CmBuffer *) * m_cmBufferCount);
56         }
57     }
58 
59     if (m_cmVmeSurfCount > 0)
60     {
61         m_cmVmeSurf       = (SurfaceIndex **)malloc(sizeof(SurfaceIndex *) * m_cmVmeSurfCount);
62         if (m_cmVmeSurf != nullptr)
63         {
64             memset(m_cmVmeSurf, 0, sizeof(SurfaceIndex *) * m_cmVmeSurfCount);
65         }
66     }
67 
68     m_surfIndex       = (SurfaceIndex **)malloc(sizeof(SurfaceIndex *) * (m_cmSurface2DCount + m_cmBufferCount + m_cmVmeSurfCount));
69     if (m_surfIndex != nullptr)
70     {
71         memset(m_surfIndex, 0, sizeof(SurfaceIndex *) * (m_cmSurface2DCount + m_cmBufferCount + m_cmVmeSurfCount));
72     }
73 }
74 
~CMRTKernelI16x16Sad()75 CMRTKernelI16x16Sad::~CMRTKernelI16x16Sad()
76 {
77     if (m_cmSurface2D != nullptr)
78     {
79         free(m_cmSurface2D);
80     }
81 
82     if (m_cmBuffer != nullptr)
83     {
84         free(m_cmBuffer);
85     }
86 
87     if (m_cmVmeSurf != nullptr)
88     {
89         free(m_cmVmeSurf);
90     }
91 
92     if (m_surfIndex != nullptr)
93     {
94         free(m_surfIndex);
95     }
96 }
97 
SetupCurbe(void * curbe)98 CM_RETURN_CODE CMRTKernelI16x16Sad::SetupCurbe(void *curbe)
99 {
100     m_curbe = curbe;
101     return CM_SUCCESS;
102 }
103 
CreateAndDispatchKernel(CmEvent * & cmEvent,bool destroyEvent,bool isEnqueue)104 CM_RETURN_CODE CMRTKernelI16x16Sad::CreateAndDispatchKernel(CmEvent *&cmEvent, bool destroyEvent, bool isEnqueue)
105 {
106     CM_RETURN_CODE r = CM_SUCCESS;
107     int32_t result;
108     uint8_t i, idx = 0;
109     uint32_t width, height, threadSpaceWidth, threadSpaceHeight;
110     uint32_t *curbe = (uint32_t *)m_curbe;
111 
112     width = curbe[0] & 0x0FFFF;
113     height = (curbe[0] >> 16) & 0x0FFFF;
114 
115     threadSpaceWidth = width >> 4;
116     threadSpaceHeight = height >> 4;
117 
118     CM_CHK_STATUS_RETURN(m_cmKernel->SetKernelArg(idx++, CURBEDATA_SIZE_I_16X16_SAD_COMPUTE, m_curbe));
119     for (i = 0; i < NUM_MBENC_I_16x16_SAD_SURFACES; i++)
120     {
121        CM_CHK_STATUS_RETURN(m_cmKernel->SetKernelArg(idx++, sizeof(SurfaceIndex), m_surfIndex[i]));
122     }
123 
124     CM_CHK_STATUS_RETURN(m_cmKernel->SetThreadCount(threadSpaceWidth * threadSpaceHeight));
125     //create Thread Space
126     result = CreateThreadSpace(threadSpaceWidth, threadSpaceHeight);
127     if (result != CM_SUCCESS)
128     {
129         printf("CM Create ThreadSpace error : %d", result);
130         return (CM_RETURN_CODE)result;
131     }
132 
133     r = AddKernel(cmEvent, destroyEvent, isEnqueue);
134     return r;
135 }
136 
AllocateSurfaces(void * params)137 CM_RETURN_CODE CMRTKernelI16x16SadUMD::AllocateSurfaces(void *params)
138 {
139     IFrameKernelParams *I16x16SadParams = (IFrameKernelParams *)params;
140 
141     CM_CHK_STATUS_RETURN(m_cmDev->CreateSurface2D((MOS_RESOURCE *)I16x16SadParams->m_cmSurfCurrY, m_cmSurface2D[0]));
142     CM_CHK_STATUS_RETURN(m_cmSurface2D[0]->GetIndex(m_surfIndex[0]));
143     CM_CHK_STATUS_RETURN(m_cmDev->CreateBuffer((MOS_RESOURCE *)I16x16SadParams->m_cmSurfSAD16x16, m_cmBuffer[0]));
144     CM_CHK_STATUS_RETURN(m_cmBuffer[0]->GetIndex(m_surfIndex[1]));
145     CM_CHK_STATUS_RETURN(m_cmDev->CreateBuffer((MOS_RESOURCE *)I16x16SadParams->m_cmSurfPer32x32PUDataOut, m_cmBuffer[1]));
146     CM_CHK_STATUS_RETURN(m_cmBuffer[1]->GetIndex(m_surfIndex[2]));
147     CM_CHK_STATUS_RETURN(m_cmDev->CreateSurface2D((MOS_RESOURCE *)I16x16SadParams->m_cmSurfSliceMap, m_cmSurface2D[1]));
148     CM_CHK_STATUS_RETURN(m_cmSurface2D[1]->GetIndex(m_surfIndex[3]));
149     CM_CHK_STATUS_RETURN(m_cmDev->CreateSurface2D((MOS_RESOURCE *)I16x16SadParams->m_cmSurfSIF, m_cmSurface2D[2]));
150     CM_CHK_STATUS_RETURN(m_cmSurface2D[2]->GetIndex(m_surfIndex[4]));
151     m_surfIndex[5] = (SurfaceIndex *)CM_NULL_SURFACE;
152 
153     return CM_SUCCESS;
154 }
155 
156