1 /*
2 * Copyright (c) 2018, 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 vphal_render_vebox_denoise.cpp
24 //! \brief Handles rendering operations for vebox denoise
25 //! \details Handles rendering operations for vebox denoise
26 //!
27 #include "vphal_render_vebox_denoise.h"
28 #include <cstring>
29 #include <new>
30 #include <string>
31 #include <vector>
32
33 #if !EMUL
34 const std::string DumpRoot("C:\\temp\\HVS\\");
35 const std::string OutputDumpDirectory(DumpRoot + "Output\\");
36
HVSDenoise(const PRENDERHAL_INTERFACE vphalRenderer,void * kernelBinary,int32_t kerneBinarySize)37 HVSDenoise::HVSDenoise(const PRENDERHAL_INTERFACE vphalRenderer, void *kernelBinary, int32_t kerneBinarySize):
38 VPCmRenderer("HVSDenoise"),
39 m_cmProgram(nullptr),
40 m_cmKernel(nullptr),
41 m_payload(nullptr)
42 {
43 m_cmProgram = LoadProgram(kernelBinary, kerneBinarySize);
44 if (!m_cmProgram)
45 {
46 VPHAL_RENDER_ASSERTMESSAGE("CM LoadProgram error\n");
47 }
48
49 CmDevice *dev = CmContext::GetCmContext().GetCmDevice();
50 int result = dev->CreateKernel(m_cmProgram, _NAME(getDenoiseFactor), m_cmKernel);
51 if (result != CM_SUCCESS)
52 {
53 VPHAL_RENDER_ASSERTMESSAGE("[%s]: CM CreateKernel error %d\n", mName.c_str(), result);
54 }
55 }
56
~HVSDenoise()57 HVSDenoise::~HVSDenoise()
58 {
59 CmDevice *dev = CmContext::GetCmContext().GetCmDevice();
60 if (m_cmKernel)
61 {
62 dev->DestroyKernel(m_cmKernel);
63 }
64
65 if (m_cmProgram)
66 {
67 dev->DestroyProgram(m_cmProgram);
68 }
69
70 m_payload = nullptr;
71 }
72
AttachPayload(void * payload)73 void HVSDenoise::AttachPayload(void *payload)
74 {
75 m_payload = static_cast<HVSDenoisePayload *>(payload);
76 }
77
GetKernelToRun(std::string & name)78 CmKernel* HVSDenoise::GetKernelToRun(std::string &name)
79 {
80 name = "HVSDenoise";
81 return m_cmKernel;
82 }
83
GetThreadSpaceDimension(int & tsWidth,int & tsHeight,int & tsColor)84 void HVSDenoise::GetThreadSpaceDimension(int &tsWidth, int &tsHeight, int &tsColor)
85 {
86 tsWidth = tsHeight = tsColor = 1;
87 }
88
PrepareKernel(CmKernel * kernel)89 void HVSDenoise::PrepareKernel(CmKernel *kernel)
90 {
91 uint16_t value_QP = 0;
92
93 if (m_payload->QP <= 18)
94 {
95 value_QP = 0;
96 }
97 else if (m_payload->QP <= 22)
98 {
99 value_QP = 1;
100 }
101 else if (m_payload->QP <= 27)
102 {
103 value_QP = 2;
104 }
105 else if (m_payload->QP <= 32)
106 {
107 value_QP = 3;
108 }
109 else if (m_payload->QP <= 37)
110 {
111 value_QP = 4;
112 }
113
114 kernel->SetKernelArg(0, sizeof(SurfaceIndex), m_payload->denoiseParam->GetCmSurfaceIndex());
115 kernel->SetKernelArg(1, sizeof(uint16_t), &value_QP);
116 kernel->SetKernelArg(2, sizeof(uint16_t), &m_payload->Strength);
117 }
118
Dump()119 void HVSDenoise::Dump()
120 {
121 int width = 0, height = 0, depth = 0;
122 m_payload->denoiseParam->DumpSurfaceToFile(OutputDumpDirectory + std::to_string(width) + "x" + std::to_string(height) + ".dat");
123 }
124
VphalHVSDenoiser(PRENDERHAL_INTERFACE renderHal)125 VphalHVSDenoiser::VphalHVSDenoiser(PRENDERHAL_INTERFACE renderHal) :
126 m_eventManager(nullptr),
127 m_renderHal(renderHal),
128 m_hvsDenoiseCmSurface(nullptr),
129 m_hvsDenoiseParam(nullptr),
130 m_hvsDenoise(nullptr),
131 m_savedQP(0),
132 m_savedStrength(0),
133 m_initHVSDenoise(false)
134 {
135 m_eventManager = MOS_New(EventManager, "HVSEventManager");
136 VPHAL_RENDER_NORMALMESSAGE("Constructor!");
137 }
138
~VphalHVSDenoiser()139 VphalHVSDenoiser::~VphalHVSDenoiser()
140 {
141 FreeResources();
142 MOS_Delete(m_hvsDenoise);
143 MOS_Delete(m_eventManager);
144 if (m_initHVSDenoise)
145 {
146 CmContext::GetCmContext().DecRefCount();
147 m_initHVSDenoise = false;
148 }
149
150 VPHAL_RENDER_NORMALMESSAGE("Destructor!");
151 }
152
InitKernelParams(void * kernelBinary,const int32_t kerneBinarySize)153 void VphalHVSDenoiser::InitKernelParams(void *kernelBinary, const int32_t kerneBinarySize)
154 {
155 m_kernelBinary = kernelBinary;
156 m_kernelBinarySize = kerneBinarySize;
157 }
158
AllocateResouces(const uint32_t width,const uint32_t height)159 void VphalHVSDenoiser::AllocateResouces(const uint32_t width, const uint32_t height)
160 {
161 uint32_t size = width * height;
162
163 m_hvsDenoiseCmSurface = MOS_New(VpCmSurfaceHolder<CmBuffer>, size, 1, 1, GMM_FORMAT_A8_UNORM_TYPE);
164 if (nullptr == m_hvsDenoiseCmSurface)
165 {
166 VPHAL_RENDER_NORMALMESSAGE("[0x%x] Failed to Allocate m_hvsDenoiseCmSurface(gpu memory) GMM_FORMAT_A8_UNORM_TYPE %d*%d!", this, width, height);
167 }
168 m_hvsDenoiseParam = MOS_NewArray(uint8_t, size);
169 if (nullptr == m_hvsDenoiseParam)
170 {
171 VPHAL_RENDER_NORMALMESSAGE("[0x%x] Failed to Allocate m_hvsDenoiseParam(cpu memory) uint8_t %d*%d!", this, width, height);
172 }
173 }
174
FreeResources()175 void VphalHVSDenoiser::FreeResources()
176 {
177 MOS_DeleteArray(m_hvsDenoiseParam);
178 MOS_Delete(m_hvsDenoiseCmSurface);
179 }
180
Render(const PVPHAL_SURFACE pSrcSuface)181 MOS_STATUS VphalHVSDenoiser::Render(const PVPHAL_SURFACE pSrcSuface)
182 {
183 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
184 uint16_t qp = 18;
185 uint16_t strength = 10;
186
187 VPHAL_RENDER_CHK_NULL_RETURN(pSrcSuface);
188 VPHAL_RENDER_CHK_NULL_RETURN(pSrcSuface->pDenoiseParams);
189
190 qp = pSrcSuface->pDenoiseParams->HVSDenoise.QP;
191 strength = pSrcSuface->pDenoiseParams->HVSDenoise.Strength;
192
193 VPHAL_RENDER_NORMALMESSAGE("qp: %d, strength: %d", qp, strength);
194
195 if (nullptr == m_hvsDenoise)
196 {
197 CmContext::sOsContext = m_renderHal->pOsInterface->pOsContext;
198 CmContext::GetCmContext().AddRefCount();
199
200 m_hvsDenoise = MOS_New(HVSDenoise, m_renderHal, m_kernelBinary, m_kernelBinarySize);
201 AllocateResouces(m_denoiseBufferInBytes, 1);
202
203 m_initHVSDenoise = true;
204
205 VPHAL_RENDER_NORMALMESSAGE("[0x%x] Init HVSDenoise[0x%x] and Allocate necessary resource!", this, m_hvsDenoise);
206 }
207
208 if (qp != m_savedQP || strength != m_savedStrength)
209 {
210 HVSDenoise::HVSDenoisePayload denoisePayload = {0};
211 denoisePayload.denoiseParam = m_hvsDenoiseCmSurface;
212 denoisePayload.Strength = strength;
213 denoisePayload.QP = qp;
214
215 CmContext::GetCmContext().ConnectEventListener(m_eventManager);
216 m_hvsDenoise->Render(&denoisePayload);
217 CmContext::GetCmContext().FlushBatchTask(false);
218 CmContext::GetCmContext().ConnectEventListener(nullptr);
219
220 m_hvsDenoiseCmSurface->GetCmSurface()->ReadSurface((uint8_t *)m_hvsDenoiseParam, nullptr, m_denoiseBufferInBytes);
221
222 m_savedQP = qp;
223 m_savedStrength = strength;
224
225 VPHAL_RENDER_NORMALMESSAGE("Render qp %d, strength %d!", qp, strength);
226 }
227
228 return eStatus;
229 }
230
231 #endif //!EMUL
232