/* * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "render_node_bloom.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "util/log.h" // shaders #include using namespace BASE_NS; RENDER_BEGIN_NAMESPACE() namespace { constexpr uint32_t UBO_OFFSET_ALIGNMENT { PipelineLayoutConstants::MIN_UBO_BIND_OFFSET_ALIGNMENT_BYTE_SIZE }; constexpr uint32_t MAX_POST_PROCESS_EFFECT_COUNT { 2 }; RenderHandleReference CreatePostProcessDataUniformBuffer( IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderHandleReference& handle) { PLUGIN_STATIC_ASSERT(sizeof(GlobalPostProcessStruct) == UBO_OFFSET_ALIGNMENT); PLUGIN_STATIC_ASSERT(sizeof(LocalPostProcessStruct) == UBO_OFFSET_ALIGNMENT); return gpuResourceMgr.Create(handle, GpuBufferDesc { CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT, (CORE_MEMORY_PROPERTY_HOST_VISIBLE_BIT | CORE_MEMORY_PROPERTY_HOST_COHERENT_BIT), CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER, UBO_OFFSET_ALIGNMENT * MAX_POST_PROCESS_EFFECT_COUNT }); } } // namespace void RenderNodeBloom::InitNode(IRenderNodeContextManager& renderNodeContextMgr) { renderNodeContextMgr_ = &renderNodeContextMgr; ParseRenderNodeInputs(); if (jsonInputs_.renderDataStore.dataStoreName.empty()) { PLUGIN_LOG_E("RenderNodeBloom: render data store configuration not set in render node graph"); } postProcessUbo_ = CreatePostProcessDataUniformBuffer(renderNodeContextMgr_->GetGpuResourceManager(), postProcessUbo_); ProcessPostProcessConfiguration(renderNodeContextMgr_->GetRenderDataStoreManager()); renderNodeContextMgr.GetDescriptorSetManager().ResetAndReserve(renderBloom_.GetDescriptorCounts()); const RenderBloom::BloomInfo info { inputResources_.customInputImages[0].handle, inputResources_.customOutputImages[0].handle, postProcessUbo_.GetHandle(), ppConfig_.bloomConfiguration.useCompute }; renderBloom_.Init(renderNodeContextMgr, info); } void RenderNodeBloom::PreExecuteFrame() { const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil(); if (jsonInputs_.hasChangeableResourceHandles) { inputResources_ = renderNodeUtil.CreateInputResources(jsonInputs_.resources); } ProcessPostProcessConfiguration(renderNodeContextMgr_->GetRenderDataStoreManager()); UpdatePostProcessData(ppConfig_); const RenderBloom::BloomInfo info { inputResources_.customInputImages[0].handle, inputResources_.customOutputImages[0].handle, postProcessUbo_.GetHandle(), ppConfig_.bloomConfiguration.useCompute }; renderBloom_.PreExecute(*renderNodeContextMgr_, info, ppConfig_); } void RenderNodeBloom::ExecuteFrame(IRenderCommandList& cmdList) { renderBloom_.Execute(*renderNodeContextMgr_, cmdList, ppConfig_); } void RenderNodeBloom::ProcessPostProcessConfiguration(const IRenderNodeRenderDataStoreManager& dataStoreMgr) { if (!jsonInputs_.renderDataStore.dataStoreName.empty()) { auto const dataStore = static_cast( dataStoreMgr.GetRenderDataStore(jsonInputs_.renderDataStore.dataStoreName)); if (dataStore) { auto const dataView = dataStore->Get(jsonInputs_.renderDataStore.configurationName); if (dataView.data() && (dataView.size_bytes() == sizeof(PostProcessConfiguration))) { ppConfig_ = *((const PostProcessConfiguration*)dataView.data()); } } } } void RenderNodeBloom::ParseRenderNodeInputs() { const IRenderNodeParserUtil& parserUtil = renderNodeContextMgr_->GetRenderNodeParserUtil(); const auto jsonVal = renderNodeContextMgr_->GetNodeJson(); jsonInputs_.resources = parserUtil.GetInputResources(jsonVal, "resources"); jsonInputs_.renderDataStore = parserUtil.GetRenderDataStore(jsonVal, "renderDataStore"); const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil(); inputResources_ = renderNodeUtil.CreateInputResources(jsonInputs_.resources); } void RenderNodeBloom::UpdatePostProcessData(const PostProcessConfiguration& postProcessConfiguration) { auto& gpuResourceMgr = renderNodeContextMgr_->GetGpuResourceManager(); const RenderPostProcessConfiguration rppc = renderNodeContextMgr_->GetRenderNodeUtil().GetRenderPostProcessConfiguration(postProcessConfiguration); PLUGIN_STATIC_ASSERT(sizeof(GlobalPostProcessStruct) == sizeof(RenderPostProcessConfiguration)); if (auto data = reinterpret_cast(gpuResourceMgr.MapBuffer(postProcessUbo_.GetHandle())); data) { const auto* dataEnd = data + sizeof(RenderPostProcessConfiguration); if (!CloneData(data, size_t(dataEnd - data), &rppc, sizeof(RenderPostProcessConfiguration))) { PLUGIN_LOG_E("post process ubo copying failed."); } gpuResourceMgr.UnmapBuffer(postProcessUbo_.GetHandle()); } } // for plugin / factory interface IRenderNode* RenderNodeBloom::Create() { return new RenderNodeBloom(); } void RenderNodeBloom::Destroy(IRenderNode* instance) { delete static_cast(instance); } RENDER_END_NAMESPACE()