1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "render_data_store_post_process.h"
17
18 #include <cstdint>
19
20 #include <base/containers/fixed_string.h>
21 #include <base/math/matrix.h>
22 #include <render/datastore/render_data_store_render_pods.h>
23 #include <render/device/intf_shader_manager.h>
24 #include <render/intf_render_context.h>
25
26 #include "datastore/render_data_store_manager.h"
27 #include "datastore/render_data_store_pod.h"
28 #include "loader/json_util.h"
29 #include "util/log.h"
30
31 using namespace BASE_NS;
32 using namespace CORE_NS;
33
34 RENDER_BEGIN_NAMESPACE()
35 namespace {
36 constexpr string_view RENDER_DATA_STORE_POST_PROCESS_TYPE_NAME { RenderDataStorePostProcess::TYPE_NAME };
37 constexpr string_view RENDER_DATA_STORE_POD_NAME { RenderDataStorePod::TYPE_NAME };
38
39 constexpr string_view CUSTOM_PROPERTIES = "customProperties";
40 constexpr string_view GLOBAL_FACTOR = "globalFactor";
41 constexpr string_view CUSTOM_PROPERTY_DATA = "data";
42
43 constexpr uint32_t SIZE_OF_FLOAT { sizeof(float) };
44 constexpr uint32_t SIZE_OF_VEC2 { sizeof(Math::Vec2) };
45 constexpr uint32_t SIZE_OF_VEC3 { sizeof(Math::Vec3) };
46 constexpr uint32_t SIZE_OF_VEC4 { sizeof(Math::Vec4) };
47 constexpr uint32_t SIZE_OF_MAT3X3 { sizeof(Math::Mat3X3) };
48 constexpr uint32_t SIZE_OF_MAT4X4 { sizeof(Math::Mat4X4) };
49
50 constexpr uint32_t ALIGNMENT_OF_FLOAT { sizeof(float) };
51 constexpr uint32_t ALIGNMENT_OF_VEC2 { sizeof(float) * 2U };
52 constexpr uint32_t ALIGNMENT_OF_VEC3 { sizeof(float) * 4U };
53 constexpr uint32_t ALIGNMENT_OF_VEC4 { sizeof(float) * 4U };
54 constexpr uint32_t ALIGNMENT_OF_MAT3X3 { sizeof(float) * 4U * 3U };
55 constexpr uint32_t ALIGNMENT_OF_MAT4X4 { sizeof(float) * 4U * 4U };
56
57 constexpr uint32_t MAX_LOCAL_DATA_BYTE_SIZE { PostProcessConstants::USER_LOCAL_FACTOR_BYTE_SIZE };
58 constexpr uint32_t MAX_GLOBAL_FACTOR_BYTE_SIZE { sizeof(Math::Vec4) };
59
60 constexpr string_view TAA_SHADER_NAME { "rendershaders://shader/fullscreen_taa.shader" };
61 constexpr string_view FXAA_SHADER_NAME { "rendershaders://shader/fullscreen_fxaa.shader" };
62 constexpr string_view DOF_SHADER_NAME { "rendershaders://shader/depth_of_field.shader" };
63 constexpr string_view MB_SHADER_NAME { "rendershaders://shader/fullscreen_motion_blur.shader" };
64
GetAlignment(uint32_t value,uint32_t align)65 inline constexpr uint32_t GetAlignment(uint32_t value, uint32_t align)
66 {
67 if (align == 0) {
68 return value;
69 } else {
70 return ((value + align - 1U) / align) * align;
71 }
72 }
73
AppendValues(const uint32_t maxByteSize,const string_view type,const json::value * value,uint32_t & offset,uint8_t * data)74 void AppendValues(
75 const uint32_t maxByteSize, const string_view type, const json::value* value, uint32_t& offset, uint8_t* data)
76 {
77 if (type == "vec4") {
78 if ((offset + ALIGNMENT_OF_VEC4) <= maxByteSize) {
79 auto* val = reinterpret_cast<Math::Vec4*>(data + offset);
80 SafeFromJsonValue(value, *val);
81 offset = GetAlignment(offset + SIZE_OF_VEC4, ALIGNMENT_OF_VEC4);
82 }
83 } else if (type == "uvec4") {
84 if ((offset + ALIGNMENT_OF_VEC4) <= maxByteSize) {
85 auto* val = reinterpret_cast<Math::UVec4*>(data + offset);
86 SafeFromJsonValue(value, *val);
87 offset = GetAlignment(offset + SIZE_OF_VEC4, ALIGNMENT_OF_VEC4);
88 }
89 } else if (type == "ivec4") {
90 if ((offset + ALIGNMENT_OF_VEC4) <= maxByteSize) {
91 auto* val = reinterpret_cast<Math::IVec4*>(data + offset);
92 SafeFromJsonValue(value, *val);
93 offset = GetAlignment(offset + SIZE_OF_VEC4, ALIGNMENT_OF_VEC4);
94 }
95 } else if (type == "vec3") {
96 if ((offset + ALIGNMENT_OF_VEC3) <= maxByteSize) {
97 auto* val = reinterpret_cast<Math::Vec3*>(data + offset);
98 SafeFromJsonValue(value, *val);
99 offset = GetAlignment(offset + SIZE_OF_VEC3, ALIGNMENT_OF_VEC3);
100 }
101 } else if (type == "uvec3") {
102 if ((offset + ALIGNMENT_OF_VEC3) <= maxByteSize) {
103 auto* val = reinterpret_cast<Math::UVec3*>(data + offset);
104 SafeFromJsonValue(value, *val);
105 offset = GetAlignment(offset + SIZE_OF_VEC3, ALIGNMENT_OF_VEC3);
106 }
107 } else if (type == "ivec3") {
108 if ((offset + ALIGNMENT_OF_VEC3) <= maxByteSize) {
109 auto* val = reinterpret_cast<Math::IVec3*>(data + offset);
110 SafeFromJsonValue(value, *val);
111 offset = GetAlignment(offset + SIZE_OF_VEC3, ALIGNMENT_OF_VEC3);
112 }
113 } else if (type == "vec2") {
114 if ((offset + ALIGNMENT_OF_VEC2) <= maxByteSize) {
115 auto* val = reinterpret_cast<Math::Vec2*>(data + offset);
116 SafeFromJsonValue(value, *val);
117 offset = GetAlignment(offset + SIZE_OF_VEC2, ALIGNMENT_OF_VEC2);
118 }
119 } else if (type == "uvec2") {
120 if ((offset + ALIGNMENT_OF_VEC2) <= maxByteSize) {
121 auto* val = reinterpret_cast<Math::UVec2*>(data + offset);
122 SafeFromJsonValue(value, *val);
123 offset = GetAlignment(offset + SIZE_OF_VEC2, ALIGNMENT_OF_VEC2);
124 }
125 } else if (type == "ivec2") {
126 if ((offset + ALIGNMENT_OF_VEC2) <= maxByteSize) {
127 auto* val = reinterpret_cast<Math::IVec2*>(data + offset);
128 SafeFromJsonValue(value, *val);
129 offset = GetAlignment(offset + SIZE_OF_VEC2, ALIGNMENT_OF_VEC2);
130 }
131 } else if (type == "float") {
132 if ((offset + ALIGNMENT_OF_FLOAT) <= maxByteSize) {
133 auto* val = reinterpret_cast<float*>(data + offset);
134 SafeFromJsonValue(value, *val);
135 offset = GetAlignment(offset + SIZE_OF_FLOAT, ALIGNMENT_OF_FLOAT);
136 }
137 } else if (type == "uint") {
138 if ((offset + ALIGNMENT_OF_FLOAT) <= maxByteSize) {
139 auto* val = reinterpret_cast<uint32_t*>(data + offset);
140 SafeFromJsonValue(value, *val);
141 offset = GetAlignment(offset + SIZE_OF_FLOAT, ALIGNMENT_OF_FLOAT);
142 }
143 } else if (type == "int") {
144 if ((offset + ALIGNMENT_OF_FLOAT) <= maxByteSize) {
145 auto* val = reinterpret_cast<int32_t*>(data + offset);
146 SafeFromJsonValue(value, *val);
147 offset = GetAlignment(offset + SIZE_OF_FLOAT, ALIGNMENT_OF_FLOAT);
148 }
149 } else if (type == "mat3x3") {
150 if ((offset + ALIGNMENT_OF_MAT3X3) <= maxByteSize) {
151 auto* val = reinterpret_cast<Math::Mat3X3*>(data + offset);
152 SafeFromJsonValue(value, *val);
153 offset = GetAlignment(offset + SIZE_OF_MAT3X3, ALIGNMENT_OF_MAT3X3);
154 }
155 } else if (type == "mat4x4") {
156 if ((offset + ALIGNMENT_OF_MAT4X4) <= maxByteSize) {
157 auto* val = reinterpret_cast<Math::Mat4X4*>(data + offset);
158 SafeFromJsonValue(value, *val);
159 offset = GetAlignment(offset + SIZE_OF_MAT4X4, ALIGNMENT_OF_MAT4X4);
160 }
161 } else {
162 PLUGIN_LOG_W("RENDER_VALIDATION: Invalid property type only int, uint, float, and XvecX variants, and mat3x3 "
163 "and mat4x4 supported");
164 }
165 // NOTE: does not handle invalid types
166 }
167 } // namespace
168
RenderDataStorePostProcess(const IRenderContext & renderContext,const string_view name)169 RenderDataStorePostProcess::RenderDataStorePostProcess(const IRenderContext& renderContext, const string_view name)
170 : renderContext_(renderContext), name_(name)
171 {}
172
Ref()173 void RenderDataStorePostProcess::Ref()
174 {
175 refcnt_.fetch_add(1, std::memory_order_relaxed);
176 }
177
Unref()178 void RenderDataStorePostProcess::Unref()
179 {
180 if (std::atomic_fetch_sub_explicit(&refcnt_, 1, std::memory_order_release) == 1) {
181 std::atomic_thread_fence(std::memory_order_acquire);
182 delete this;
183 }
184 }
185
GetRefCount()186 int32_t RenderDataStorePostProcess::GetRefCount()
187 {
188 return refcnt_;
189 }
190
Create(const string_view name)191 void RenderDataStorePostProcess::Create(const string_view name)
192 {
193 const auto lock = std::lock_guard(mutex_);
194
195 if (!allPostProcesses_.contains(name)) {
196 CreateFromPod(name);
197 } else {
198 PLUGIN_LOG_I("Render data store post process with name (%s) already created.", name.data());
199 }
200 }
201
Create(const string_view name,const string_view ppName,const RenderHandleReference & shader)202 void RenderDataStorePostProcess::Create(
203 const string_view name, const string_view ppName, const RenderHandleReference& shader)
204 {
205 const auto lock = std::lock_guard(mutex_);
206
207 if (!allPostProcesses_.contains(name)) {
208 CreateFromPod(name);
209 }
210
211 if (auto iter = allPostProcesses_.find(name); iter != allPostProcesses_.end()) {
212 auto& postProcesses = iter->second.postProcesses;
213 const auto ppCount = static_cast<uint32_t>(postProcesses.size());
214 uint32_t ppIndex = ~0u;
215 for (uint32_t idx = 0; idx < ppCount; ++idx) {
216 if (postProcesses[idx].name == ppName) {
217 ppIndex = idx;
218 break;
219 }
220 }
221
222 if (ppIndex < ppCount) {
223 // does not set variables
224 GetShaderProperties(shader, postProcesses[ppIndex].variables);
225 SetGlobalFactorsImpl(postProcesses[ppIndex].variables, ppIndex, iter->second);
226 } else {
227 PostProcess pp;
228 pp.id = static_cast<uint32_t>(postProcesses.size());
229 pp.name = ppName;
230 pp.shader = shader;
231 pp.variables = {}; // default variables, overwritten with shader default properties
232 GetShaderProperties(shader, pp.variables);
233 postProcesses.push_back(move(pp));
234 SetGlobalFactorsImpl(postProcesses[pp.id].variables, pp.id, iter->second);
235 }
236 } else {
237 PLUGIN_LOG_E("Post process creation error (name: %s, ppName: %s)", name.data(), ppName.data());
238 }
239 }
240
Destroy(const string_view name)241 void RenderDataStorePostProcess::Destroy(const string_view name)
242 {
243 const auto lock = std::lock_guard(mutex_);
244
245 if ((!name.empty()) && allPostProcesses_.contains(name)) {
246 allPostProcesses_.erase(name);
247 if (refcnt_ptr<IRenderDataStorePod> dataStorePod =
248 renderContext_.GetRenderDataStoreManager().GetRenderDataStore(RENDER_DATA_STORE_POD_NAME)) {
249 dataStorePod->DestroyPod(RENDER_DATA_STORE_POST_PROCESS_TYPE_NAME, name);
250 }
251 } else {
252 PLUGIN_LOG_I("Post process not found: %s", name.data());
253 }
254 }
255
Destroy(const string_view name,const string_view ppName)256 void RenderDataStorePostProcess::Destroy(const string_view name, const string_view ppName)
257 {
258 const auto lock = std::lock_guard(mutex_);
259
260 if (auto iter = allPostProcesses_.find(name); iter != allPostProcesses_.end()) {
261 for (auto ppIter = iter->second.postProcesses.begin(); ppIter != iter->second.postProcesses.end(); ++ppIter) {
262 if (ppIter->name == ppName) {
263 iter->second.postProcesses.erase(ppIter);
264 break;
265 }
266 }
267 }
268 }
269
Contains(const string_view name) const270 bool RenderDataStorePostProcess::Contains(const string_view name) const
271 {
272 const auto lock = std::lock_guard(mutex_);
273
274 return allPostProcesses_.contains(name);
275 }
276
Contains(const string_view name,const string_view ppName) const277 bool RenderDataStorePostProcess::Contains(const string_view name, const string_view ppName) const
278 {
279 const auto lock = std::lock_guard(mutex_);
280
281 if (const auto iter = allPostProcesses_.find(name); iter != allPostProcesses_.cend()) {
282 for (const auto& ref : iter->second.postProcesses) {
283 if (ref.name == ppName) {
284 return true;
285 }
286 }
287 }
288 return false;
289 }
290
Set(const string_view name,const string_view ppName,const PostProcess::Variables & vars)291 void RenderDataStorePostProcess::Set(
292 const string_view name, const string_view ppName, const PostProcess::Variables& vars)
293 {
294 const auto lock = std::lock_guard(mutex_);
295
296 if (auto iter = allPostProcesses_.find(name); iter != allPostProcesses_.end()) {
297 auto& postProcesses = iter->second.postProcesses;
298 const auto ppCount = static_cast<uint32_t>(postProcesses.size());
299 for (uint32_t idx = 0; idx < ppCount; ++idx) {
300 if (postProcesses[idx].name == ppName) {
301 SetImpl(vars, idx, iter->second);
302 break;
303 }
304 }
305 }
306 }
307
Set(const string_view name,const array_view<PostProcess::Variables> vars)308 void RenderDataStorePostProcess::Set(const string_view name, const array_view<PostProcess::Variables> vars)
309 {
310 const auto lock = std::lock_guard(mutex_);
311
312 if (auto iter = allPostProcesses_.find(name); iter != allPostProcesses_.end()) {
313 const auto& postProcesses = iter->second.postProcesses;
314 const uint32_t ppCount =
315 Math::min(static_cast<uint32_t>(vars.size()), static_cast<uint32_t>(postProcesses.size()));
316 for (uint32_t idx = 0; idx < ppCount; ++idx) {
317 SetImpl(vars[idx], idx, iter->second);
318 }
319 }
320 }
321
GetGlobalFactors(const string_view name) const322 RenderDataStorePostProcess::GlobalFactors RenderDataStorePostProcess::GetGlobalFactors(const string_view name) const
323 {
324 const auto lock = std::lock_guard(mutex_);
325
326 if (auto iter = allPostProcesses_.find(name); iter != allPostProcesses_.end()) {
327 return iter->second.globalFactors;
328 } else {
329 return {};
330 }
331 }
332
Get(const string_view name) const333 vector<RenderDataStorePostProcess::PostProcess> RenderDataStorePostProcess::Get(const string_view name) const
334 {
335 const auto lock = std::lock_guard(mutex_);
336
337 if (const auto iter = allPostProcesses_.find(name); iter != allPostProcesses_.cend()) {
338 return iter->second.postProcesses;
339 }
340 return {};
341 }
342
Get(const string_view name,const string_view ppName) const343 RenderDataStorePostProcess::PostProcess RenderDataStorePostProcess::Get(
344 const string_view name, const string_view ppName) const
345 {
346 const auto lock = std::lock_guard(mutex_);
347
348 if (const auto iter = allPostProcesses_.find(name); iter != allPostProcesses_.cend()) {
349 for (const auto& ref : iter->second.postProcesses) {
350 if (ppName == ref.name) {
351 return ref;
352 }
353 }
354 }
355 return {};
356 }
357
CreateFromPod(const string_view name)358 void RenderDataStorePostProcess::CreateFromPod(const string_view name)
359 {
360 // create base post process render data store
361 if (refcnt_ptr<IRenderDataStorePod> dataStorePod =
362 renderContext_.GetRenderDataStoreManager().GetRenderDataStore(RENDER_DATA_STORE_POD_NAME)) {
363 PLUGIN_STATIC_ASSERT(
364 countof(PostProcessConstants::POST_PROCESS_NAMES) == PostProcessConstants::POST_PROCESS_COUNT);
365 auto& postProcessRef = allPostProcesses_[name];
366 // NOTE: needs to fetch the post process "properties" from shader custom properties
367 if (const auto arrView = dataStorePod->Get(name); arrView.size_bytes() == sizeof(PostProcessConfiguration)) {
368 // populate with built-in data and copy
369 PostProcessConfiguration ppConfig = *((const PostProcessConfiguration*)arrView.data());
370 FillDefaultPostProcessData(ppConfig, postProcessRef);
371 } else {
372 // create new
373 PostProcessConfiguration ppConfig;
374 dataStorePod->CreatePod(RENDER_DATA_STORE_POST_PROCESS_TYPE_NAME, name, arrayviewU8(ppConfig));
375 FillDefaultPostProcessData(ppConfig, postProcessRef);
376 }
377 }
378 }
379
SetImpl(const PostProcess::Variables & vars,const uint32_t ppIndex,PostProcessStack & ppStack)380 void RenderDataStorePostProcess::SetImpl(
381 const PostProcess::Variables& vars, const uint32_t ppIndex, PostProcessStack& ppStack)
382 {
383 auto& postProcesses = ppStack.postProcesses;
384 PLUGIN_ASSERT(ppIndex < static_cast<uint32_t>(postProcesses.size()));
385 postProcesses[ppIndex].variables = vars;
386 SetGlobalFactorsImpl(vars, ppIndex, ppStack);
387 }
388
SetGlobalFactorsImpl(const PostProcess::Variables & vars,const uint32_t ppIndex,PostProcessStack & ppStack)389 void RenderDataStorePostProcess::SetGlobalFactorsImpl(
390 const PostProcess::Variables& vars, const uint32_t ppIndex, PostProcessStack& ppStack)
391 {
392 PLUGIN_ASSERT(ppIndex < static_cast<uint32_t>(ppStack.postProcesses.size()));
393 // NOTE: does not copy vars
394 auto& globalFactors = ppStack.globalFactors;
395 if (ppIndex < PostProcessConstants::GLOBAL_FACTOR_COUNT) {
396 globalFactors.factors[ppIndex] = vars.factor;
397 globalFactors.enableFlags = (uint32_t(vars.enabled) << ppIndex);
398 } else if (vars.userFactorIndex < PostProcessConstants::USER_GLOBAL_FACTOR_COUNT) {
399 globalFactors.userFactors[vars.userFactorIndex] = vars.factor;
400 }
401 }
402
FillDefaultPostProcessData(const PostProcessConfiguration & ppConfig,PostProcessStack & ppStack)403 void RenderDataStorePostProcess::FillDefaultPostProcessData(
404 const PostProcessConfiguration& ppConfig, PostProcessStack& ppStack)
405 {
406 const IShaderManager& shaderMgr = renderContext_.GetDevice().GetShaderManager();
407 auto FillBuiltInData = [&](const uint32_t idx, const uint32_t factorIndex, const uint32_t userFactorIndex,
408 const Math::Vec4& factor, const string_view shaderName) {
409 PostProcess pp;
410 pp.id = idx;
411 pp.name = PostProcessConstants::POST_PROCESS_NAMES[pp.id];
412 pp.factorIndex = factorIndex;
413 pp.shader = shaderName.empty() ? RenderHandleReference {} : shaderMgr.GetShaderHandle(shaderName);
414 auto& vars = pp.variables;
415 vars.userFactorIndex = userFactorIndex;
416 vars.enabled = false;
417 vars.factor = factor;
418 ClearToValue(vars.customPropertyData, sizeof(vars.customPropertyData), 0x0, sizeof(vars.customPropertyData));
419 return pp;
420 };
421
422 constexpr uint32_t defUserIdx { ~0u };
423 ppStack.postProcesses.push_back(FillBuiltInData(PostProcessConstants::RENDER_TONEMAP,
424 PostProcessConstants::RENDER_TONEMAP, defUserIdx, PostProcessConversionHelper::GetFactorTonemap(ppConfig), {}));
425 ppStack.postProcesses.push_back(
426 FillBuiltInData(PostProcessConstants::RENDER_VIGNETTE, PostProcessConstants::RENDER_VIGNETTE, defUserIdx,
427 PostProcessConversionHelper::GetFactorVignette(ppConfig), {}));
428 ppStack.postProcesses.push_back(FillBuiltInData(PostProcessConstants::RENDER_DITHER,
429 PostProcessConstants::RENDER_DITHER, defUserIdx, PostProcessConversionHelper::GetFactorDither(ppConfig), {}));
430 ppStack.postProcesses.push_back(
431 FillBuiltInData(PostProcessConstants::RENDER_COLOR_CONVERSION, PostProcessConstants::RENDER_COLOR_CONVERSION,
432 defUserIdx, PostProcessConversionHelper::GetFactorColorConversion(ppConfig), {}));
433 ppStack.postProcesses.push_back(
434 FillBuiltInData(PostProcessConstants::RENDER_COLOR_FRINGE_BIT, PostProcessConstants::RENDER_COLOR_FRINGE_BIT,
435 defUserIdx, PostProcessConversionHelper::GetFactorFringe(ppConfig), {}));
436
437 ppStack.postProcesses.push_back(FillBuiltInData(
438 PostProcessConstants::RENDER_EMPTY_5, PostProcessConstants::RENDER_EMPTY_5, defUserIdx, {}, {}));
439 ppStack.postProcesses.push_back(FillBuiltInData(
440 PostProcessConstants::RENDER_EMPTY_6, PostProcessConstants::RENDER_EMPTY_6, defUserIdx, {}, {}));
441 ppStack.postProcesses.push_back(FillBuiltInData(
442 PostProcessConstants::RENDER_EMPTY_7, PostProcessConstants::RENDER_EMPTY_7, defUserIdx, {}, {}));
443
444 ppStack.postProcesses.push_back(FillBuiltInData(PostProcessConstants::RENDER_BLUR,
445 PostProcessConfiguration::INDEX_BLUR, defUserIdx, PostProcessConversionHelper::GetFactorBlur(ppConfig), {}));
446 ppStack.postProcesses.push_back(FillBuiltInData(PostProcessConstants::RENDER_BLOOM,
447 PostProcessConfiguration::INDEX_BLOOM, defUserIdx, PostProcessConversionHelper::GetFactorBloom(ppConfig), {}));
448 ppStack.postProcesses.push_back(
449 FillBuiltInData(PostProcessConstants::RENDER_FXAA, PostProcessConfiguration::INDEX_FXAA, defUserIdx,
450 PostProcessConversionHelper::GetFactorFxaa(ppConfig), FXAA_SHADER_NAME));
451 ppStack.postProcesses.push_back(
452 FillBuiltInData(PostProcessConstants::RENDER_TAA, PostProcessConfiguration::INDEX_TAA, defUserIdx,
453 PostProcessConversionHelper::GetFactorTaa(ppConfig), TAA_SHADER_NAME));
454 {
455 auto& pp = ppStack.postProcesses.emplace_back();
456 pp.id = PostProcessConstants::RENDER_DOF;
457 pp.name = PostProcessConstants::POST_PROCESS_NAMES[pp.id];
458 pp.factorIndex = PostProcessConfiguration::INDEX_DOF;
459 pp.shader = shaderMgr.GetShaderHandle(DOF_SHADER_NAME);
460 auto& vars = pp.variables;
461 vars.userFactorIndex = defUserIdx;
462 vars.enabled = false;
463 auto factors = PostProcessConversionHelper::GetFactorDof(ppConfig);
464 CloneData(vars.customPropertyData, sizeof(vars.customPropertyData), &factors, sizeof(factors));
465 factors = PostProcessConversionHelper::GetFactorDof2(ppConfig);
466 CloneData(vars.customPropertyData + sizeof(factors), sizeof(vars.customPropertyData) - sizeof(factors),
467 &factors, sizeof(factors));
468 }
469
470 ppStack.postProcesses.push_back(
471 FillBuiltInData(PostProcessConstants::RENDER_MOTION_BLUR, PostProcessConstants::RENDER_MOTION_BLUR, defUserIdx,
472 PostProcessConversionHelper::GetFactorMotionBlur(ppConfig), MB_SHADER_NAME));
473
474 // fill global built-in factors
475 PLUGIN_ASSERT(PostProcessConstants::POST_PROCESS_COUNT == static_cast<uint32_t>(ppStack.postProcesses.size()));
476 for (size_t idx = 0; idx < ppStack.postProcesses.size(); ++idx) {
477 ppStack.globalFactors.factors[idx] = ppStack.postProcesses[idx].variables.factor;
478 }
479 }
480
GetShaderProperties(const RenderHandleReference & shader,IRenderDataStorePostProcess::PostProcess::Variables & vars)481 void RenderDataStorePostProcess::GetShaderProperties(
482 const RenderHandleReference& shader, IRenderDataStorePostProcess::PostProcess::Variables& vars)
483 {
484 if (shader) {
485 const IShaderManager& shaderMgr = renderContext_.GetDevice().GetShaderManager();
486 if (const json::value* metaJson = shaderMgr.GetMaterialMetadata(shader); metaJson && metaJson->is_array()) {
487 for (const auto& ref : metaJson->array_) {
488 if (const auto globalFactor = ref.find(GLOBAL_FACTOR); globalFactor && globalFactor->is_array()) {
489 // process global factor "array", vec4
490 uint32_t offset = 0;
491 for (const auto& propRef : globalFactor->array_) {
492 if (propRef.is_object()) {
493 string_view type;
494 const json::value* value = nullptr;
495 for (const auto& dataObject : propRef.object_) {
496 if (dataObject.key == "type" && dataObject.value.is_string()) {
497 type = dataObject.value.string_;
498 } else if (dataObject.key == "value") {
499 value = &dataObject.value;
500 }
501 }
502 auto* factorData = reinterpret_cast<uint8_t*>(&vars.factor);
503 AppendValues(MAX_GLOBAL_FACTOR_BYTE_SIZE, type, value, offset, factorData);
504 }
505 }
506 } else if (const auto customProps = ref.find(CUSTOM_PROPERTIES);
507 customProps && customProps->is_array()) {
508 // process custom properties i.e. local factors
509 for (const auto& propRef : customProps->array_) {
510 uint32_t offset = 0;
511 if (const auto customData = propRef.find(CUSTOM_PROPERTY_DATA);
512 customData && customData->is_array()) {
513 if (offset >= MAX_LOCAL_DATA_BYTE_SIZE) {
514 break;
515 }
516
517 for (const auto& dataValue : customData->array_) {
518 if (dataValue.is_object()) {
519 string_view type;
520 const json::value* value = nullptr;
521 for (const auto& dataObject : dataValue.object_) {
522 if (dataObject.key == "type" && dataObject.value.is_string()) {
523 type = dataObject.value.string_;
524 } else if (dataObject.key == "value") {
525 value = &dataObject.value;
526 }
527 }
528 AppendValues(
529 MAX_LOCAL_DATA_BYTE_SIZE, type, value, offset, vars.customPropertyData);
530 }
531 }
532 }
533 }
534 }
535 }
536 }
537 }
538 }
539
540 // for plugin / factory interface
Create(IRenderContext & renderContext,const char * name)541 refcnt_ptr<IRenderDataStore> RenderDataStorePostProcess::Create(IRenderContext& renderContext, const char* name)
542 {
543 return refcnt_ptr<IRenderDataStore>(new RenderDataStorePostProcess(renderContext, name));
544 }
545 RENDER_END_NAMESPACE()
546