/* * Copyright (c) 2024 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 "datastore/render_data_store_pod.h" #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 }; RenderHandleReference CreatePostProcessDataUniformBuffer( IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderHandleReference& handle) { PLUGIN_STATIC_ASSERT(sizeof(GlobalPostProcessStruct) == sizeof(RenderPostProcessConfiguration)); 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, sizeof(GlobalPostProcessStruct) + sizeof(LocalPostProcessStruct) }); } inline BindableImage GetBindableImage(const RenderNodeResource& res) { return BindableImage { res.handle, res.mip, res.layer, ImageLayout::CORE_IMAGE_LAYOUT_UNDEFINED, res.secondHandle }; } } // namespace void RenderNodeBloom::InitNode(IRenderNodeContextManager& renderNodeContextMgr) { valid_ = true; renderNodeContextMgr_ = &renderNodeContextMgr; ParseRenderNodeInputs(); if (jsonInputs_.renderDataStore.dataStoreName.empty()) { PLUGIN_LOG_E("RenderNodeBloom: render data store configuration not set in render node graph"); } if (jsonInputs_.renderDataStore.typeName != RenderDataStorePod::TYPE_NAME) { PLUGIN_LOG_E("RenderNodeBloom: render data store type name not supported (%s != %s)", jsonInputs_.renderDataStore.typeName.data(), RenderDataStorePod::TYPE_NAME); valid_ = false; } postProcessUbo_ = CreatePostProcessDataUniformBuffer(renderNodeContextMgr_->GetGpuResourceManager(), postProcessUbo_); ProcessPostProcessConfiguration(renderNodeContextMgr_->GetRenderDataStoreManager()); renderNodeContextMgr.GetDescriptorSetManager().ResetAndReserve(renderBloom_.GetDescriptorCounts()); const RenderBloom::BloomInfo info { GetBindableImage(inputResources_.customInputImages[0]), GetBindableImage(inputResources_.customOutputImages[0]), postProcessUbo_.GetHandle(), ppConfig_.bloomConfiguration.useCompute }; renderBloom_.Init(renderNodeContextMgr, info); } void RenderNodeBloom::PreExecuteFrame() { if (!valid_) { return; } const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil(); if (jsonInputs_.hasChangeableResourceHandles) { inputResources_ = renderNodeUtil.CreateInputResources(jsonInputs_.resources); } ProcessPostProcessConfiguration(renderNodeContextMgr_->GetRenderDataStoreManager()); UpdatePostProcessData(ppConfig_); const RenderBloom::BloomInfo info { GetBindableImage(inputResources_.customInputImages[0]), GetBindableImage(inputResources_.customOutputImages[0]), postProcessUbo_.GetHandle(), ppConfig_.bloomConfiguration.useCompute }; renderBloom_.PreExecute(*renderNodeContextMgr_, info, ppConfig_); } void RenderNodeBloom::ExecuteFrame(IRenderCommandList& cmdList) { if (!valid_) { return; } renderBloom_.Execute(*renderNodeContextMgr_, cmdList, ppConfig_); } IRenderNode::ExecuteFlags RenderNodeBloom::GetExecuteFlags() const { // At the moment bloom needs typically copy even though it would not be in use return ExecuteFlagBits::EXECUTE_FLAG_BITS_DEFAULT; } void RenderNodeBloom::ProcessPostProcessConfiguration(const IRenderNodeRenderDataStoreManager& dataStoreMgr) { if (!jsonInputs_.renderDataStore.dataStoreName.empty()) { if (const IRenderDataStore* ds = dataStoreMgr.GetRenderDataStore(jsonInputs_.renderDataStore.dataStoreName); ds) { if (jsonInputs_.renderDataStore.typeName == RenderDataStorePod::TYPE_NAME) { auto const dataStore = static_cast(ds); 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()