18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci 168bf80f4bSopenharmony_ci#include "render_bloom.h" 178bf80f4bSopenharmony_ci 188bf80f4bSopenharmony_ci#include <base/containers/fixed_string.h> 198bf80f4bSopenharmony_ci#include <base/containers/unordered_map.h> 208bf80f4bSopenharmony_ci#include <base/math/vector.h> 218bf80f4bSopenharmony_ci#include <render/datastore/intf_render_data_store_manager.h> 228bf80f4bSopenharmony_ci#include <render/datastore/intf_render_data_store_pod.h> 238bf80f4bSopenharmony_ci#include <render/datastore/render_data_store_render_pods.h> 248bf80f4bSopenharmony_ci#include <render/device/intf_gpu_resource_manager.h> 258bf80f4bSopenharmony_ci#include <render/device/intf_shader_manager.h> 268bf80f4bSopenharmony_ci#include <render/namespace.h> 278bf80f4bSopenharmony_ci#include <render/nodecontext/intf_node_context_descriptor_set_manager.h> 288bf80f4bSopenharmony_ci#include <render/nodecontext/intf_node_context_pso_manager.h> 298bf80f4bSopenharmony_ci#include <render/nodecontext/intf_pipeline_descriptor_set_binder.h> 308bf80f4bSopenharmony_ci#include <render/nodecontext/intf_render_command_list.h> 318bf80f4bSopenharmony_ci#include <render/nodecontext/intf_render_node_context_manager.h> 328bf80f4bSopenharmony_ci#include <render/nodecontext/intf_render_node_util.h> 338bf80f4bSopenharmony_ci 348bf80f4bSopenharmony_ci#include "util/log.h" 358bf80f4bSopenharmony_ci 368bf80f4bSopenharmony_ci// shaders 378bf80f4bSopenharmony_ci#include <render/shaders/common/render_post_process_structs_common.h> 388bf80f4bSopenharmony_ci 398bf80f4bSopenharmony_ciusing namespace BASE_NS; 408bf80f4bSopenharmony_ci 418bf80f4bSopenharmony_ciRENDER_BEGIN_NAMESPACE() 428bf80f4bSopenharmony_cinamespace { 438bf80f4bSopenharmony_ciconstexpr DynamicStateEnum DYNAMIC_STATES[] = { CORE_DYNAMIC_STATE_ENUM_VIEWPORT, CORE_DYNAMIC_STATE_ENUM_SCISSOR }; 448bf80f4bSopenharmony_ci} 458bf80f4bSopenharmony_ci 468bf80f4bSopenharmony_civoid RenderBloom::Init(IRenderNodeContextManager& renderNodeContextMgr, const BloomInfo& bloomInfo) 478bf80f4bSopenharmony_ci{ 488bf80f4bSopenharmony_ci bloomInfo_ = bloomInfo; 498bf80f4bSopenharmony_ci 508bf80f4bSopenharmony_ci // NOTE: target counts etc. should probably be resized based on configuration 518bf80f4bSopenharmony_ci CreatePsos(renderNodeContextMgr); 528bf80f4bSopenharmony_ci 538bf80f4bSopenharmony_ci auto& gpuResourceMgr = renderNodeContextMgr.GetGpuResourceManager(); 548bf80f4bSopenharmony_ci samplerHandle_ = gpuResourceMgr.Create(samplerHandle_, 558bf80f4bSopenharmony_ci GpuSamplerDesc { 568bf80f4bSopenharmony_ci Filter::CORE_FILTER_LINEAR, // magFilter 578bf80f4bSopenharmony_ci Filter::CORE_FILTER_LINEAR, // minFilter 588bf80f4bSopenharmony_ci Filter::CORE_FILTER_LINEAR, // mipMapMode 598bf80f4bSopenharmony_ci SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU 608bf80f4bSopenharmony_ci SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV 618bf80f4bSopenharmony_ci SamplerAddressMode::CORE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW 628bf80f4bSopenharmony_ci }); 638bf80f4bSopenharmony_ci} 648bf80f4bSopenharmony_ci 658bf80f4bSopenharmony_civoid RenderBloom::PreExecute(IRenderNodeContextManager& renderNodeContextMgr, const BloomInfo& bloomInfo, 668bf80f4bSopenharmony_ci const PostProcessConfiguration& ppConfig) 678bf80f4bSopenharmony_ci{ 688bf80f4bSopenharmony_ci bloomInfo_ = bloomInfo; 698bf80f4bSopenharmony_ci 708bf80f4bSopenharmony_ci const GpuImageDesc& imgDesc = 718bf80f4bSopenharmony_ci renderNodeContextMgr.GetGpuResourceManager().GetImageDescriptor(bloomInfo_.input.handle); 728bf80f4bSopenharmony_ci uint32_t sizeDenom = 1u; 738bf80f4bSopenharmony_ci if (ppConfig.bloomConfiguration.bloomQualityType == BloomConfiguration::QUALITY_TYPE_LOW) { 748bf80f4bSopenharmony_ci sizeDenom = 2u; 758bf80f4bSopenharmony_ci } 768bf80f4bSopenharmony_ci CreateTargets(renderNodeContextMgr, Math::UVec2(imgDesc.width, imgDesc.height) / sizeDenom); 778bf80f4bSopenharmony_ci} 788bf80f4bSopenharmony_ci 798bf80f4bSopenharmony_civoid RenderBloom::Execute(IRenderNodeContextManager& renderNodeContextMgr, IRenderCommandList& cmdList, 808bf80f4bSopenharmony_ci const PostProcessConfiguration& ppConfig) 818bf80f4bSopenharmony_ci{ 828bf80f4bSopenharmony_ci bloomEnabled_ = false; 838bf80f4bSopenharmony_ci BloomConfiguration bloomConfiguration; 848bf80f4bSopenharmony_ci if (ppConfig.enableFlags & PostProcessConfiguration::ENABLE_BLOOM_BIT) { 858bf80f4bSopenharmony_ci bloomConfiguration.thresholdHard = ppConfig.bloomConfiguration.thresholdHard; 868bf80f4bSopenharmony_ci bloomConfiguration.thresholdSoft = ppConfig.bloomConfiguration.thresholdSoft; 878bf80f4bSopenharmony_ci bloomConfiguration.amountCoefficient = ppConfig.bloomConfiguration.amountCoefficient; 888bf80f4bSopenharmony_ci bloomConfiguration.dirtMaskCoefficient = ppConfig.bloomConfiguration.dirtMaskCoefficient; 898bf80f4bSopenharmony_ci 908bf80f4bSopenharmony_ci bloomEnabled_ = true; 918bf80f4bSopenharmony_ci } 928bf80f4bSopenharmony_ci 938bf80f4bSopenharmony_ci const auto bloomQualityType = ppConfig.bloomConfiguration.bloomQualityType; 948bf80f4bSopenharmony_ci PLUGIN_ASSERT(bloomQualityType < CORE_BLOOM_QUALITY_COUNT); 958bf80f4bSopenharmony_ci if (bloomInfo_.useCompute) { 968bf80f4bSopenharmony_ci psos_.downscale = psos_.downscaleHandlesCompute[bloomQualityType].regular; 978bf80f4bSopenharmony_ci psos_.downscaleAndThreshold = psos_.downscaleHandlesCompute[bloomQualityType].threshold; 988bf80f4bSopenharmony_ci } else { 998bf80f4bSopenharmony_ci psos_.downscale = psos_.downscaleHandles[bloomQualityType].regular; 1008bf80f4bSopenharmony_ci psos_.downscaleAndThreshold = psos_.downscaleHandles[bloomQualityType].threshold; 1018bf80f4bSopenharmony_ci } 1028bf80f4bSopenharmony_ci 1038bf80f4bSopenharmony_ci if (!bloomEnabled_) { 1048bf80f4bSopenharmony_ci bloomConfiguration.amountCoefficient = 0.0f; 1058bf80f4bSopenharmony_ci } 1068bf80f4bSopenharmony_ci 1078bf80f4bSopenharmony_ci bloomParameters_ = Math::Vec4( 1088bf80f4bSopenharmony_ci // .x = thresholdHard, luma values below this won't bloom 1098bf80f4bSopenharmony_ci bloomConfiguration.thresholdHard, 1108bf80f4bSopenharmony_ci // .y = thresholdSoft, luma values from this value to hard threshold will reduce bloom input from 1.0 -> 0.0 1118bf80f4bSopenharmony_ci // i.e. this creates softer threshold for bloom 1128bf80f4bSopenharmony_ci bloomConfiguration.thresholdSoft, 1138bf80f4bSopenharmony_ci // .z = amountCoefficient, will multiply the colors from the bloom textures when combined with original color 1148bf80f4bSopenharmony_ci // target 1158bf80f4bSopenharmony_ci bloomConfiguration.amountCoefficient, 1168bf80f4bSopenharmony_ci // .w = -will multiply the dirt mask effect 1178bf80f4bSopenharmony_ci bloomConfiguration.dirtMaskCoefficient); 1188bf80f4bSopenharmony_ci 1198bf80f4bSopenharmony_ci const bool validBinders = binders_.globalSet0.get() != nullptr; 1208bf80f4bSopenharmony_ci if (validBinders) { 1218bf80f4bSopenharmony_ci if (bloomInfo_.useCompute) { 1228bf80f4bSopenharmony_ci ComputeBloom(renderNodeContextMgr, cmdList); 1238bf80f4bSopenharmony_ci } else { 1248bf80f4bSopenharmony_ci GraphicsBloom(renderNodeContextMgr, cmdList); 1258bf80f4bSopenharmony_ci } 1268bf80f4bSopenharmony_ci } 1278bf80f4bSopenharmony_ci} 1288bf80f4bSopenharmony_ci 1298bf80f4bSopenharmony_ciDescriptorCounts RenderBloom::GetDescriptorCounts() const 1308bf80f4bSopenharmony_ci{ 1318bf80f4bSopenharmony_ci // NOTE: when added support for various bloom target counts, might need to be calculated for max 1328bf80f4bSopenharmony_ci return DescriptorCounts { { 1338bf80f4bSopenharmony_ci { CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 32u }, 1348bf80f4bSopenharmony_ci { CORE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 32u }, 1358bf80f4bSopenharmony_ci { CORE_DESCRIPTOR_TYPE_STORAGE_IMAGE, 32u }, 1368bf80f4bSopenharmony_ci { CORE_DESCRIPTOR_TYPE_SAMPLER, 24u }, 1378bf80f4bSopenharmony_ci { CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2u }, 1388bf80f4bSopenharmony_ci } }; 1398bf80f4bSopenharmony_ci} 1408bf80f4bSopenharmony_ci 1418bf80f4bSopenharmony_ciRenderHandle RenderBloom::GetFinalTarget() const 1428bf80f4bSopenharmony_ci{ 1438bf80f4bSopenharmony_ci if (RenderHandleUtil::IsValid(bloomInfo_.output.handle)) { 1448bf80f4bSopenharmony_ci return bloomInfo_.output.handle; 1458bf80f4bSopenharmony_ci } else { 1468bf80f4bSopenharmony_ci // output tex1 on compute and tex2 on graphics 1478bf80f4bSopenharmony_ci return bloomInfo_.useCompute ? (targets_.tex1[0u].GetHandle()) : (targets_.tex2[0u].GetHandle()); 1488bf80f4bSopenharmony_ci } 1498bf80f4bSopenharmony_ci} 1508bf80f4bSopenharmony_ci 1518bf80f4bSopenharmony_civoid RenderBloom::UpdateGlobalSet(IRenderCommandList& cmdList) 1528bf80f4bSopenharmony_ci{ 1538bf80f4bSopenharmony_ci auto& binder = *binders_.globalSet0; 1548bf80f4bSopenharmony_ci binder.ClearBindings(); 1558bf80f4bSopenharmony_ci uint32_t binding = 0u; 1568bf80f4bSopenharmony_ci binder.BindBuffer(binding++, bloomInfo_.globalUbo, 0); 1578bf80f4bSopenharmony_ci binder.BindBuffer(binding++, bloomInfo_.globalUbo, sizeof(GlobalPostProcessStruct)); 1588bf80f4bSopenharmony_ci cmdList.UpdateDescriptorSet(binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources()); 1598bf80f4bSopenharmony_ci} 1608bf80f4bSopenharmony_ci 1618bf80f4bSopenharmony_civoid RenderBloom::ComputeBloom(IRenderNodeContextManager& renderNodeContextMgr, IRenderCommandList& cmdList) 1628bf80f4bSopenharmony_ci{ 1638bf80f4bSopenharmony_ci constexpr PushConstant pc { ShaderStageFlagBits::CORE_SHADER_STAGE_COMPUTE_BIT, 1648bf80f4bSopenharmony_ci sizeof(LocalPostProcessPushConstantStruct) }; 1658bf80f4bSopenharmony_ci 1668bf80f4bSopenharmony_ci UpdateGlobalSet(cmdList); 1678bf80f4bSopenharmony_ci if (bloomEnabled_) { 1688bf80f4bSopenharmony_ci ComputeDownscaleAndThreshold(pc, cmdList); 1698bf80f4bSopenharmony_ci ComputeDownscale(pc, cmdList); 1708bf80f4bSopenharmony_ci ComputeUpscale(pc, cmdList); 1718bf80f4bSopenharmony_ci } 1728bf80f4bSopenharmony_ci // needs to be done even when bloom is disabled if node is in use 1738bf80f4bSopenharmony_ci if (RenderHandleUtil::IsValid(bloomInfo_.output.handle)) { 1748bf80f4bSopenharmony_ci ComputeCombine(pc, cmdList); 1758bf80f4bSopenharmony_ci } 1768bf80f4bSopenharmony_ci} 1778bf80f4bSopenharmony_ci 1788bf80f4bSopenharmony_civoid RenderBloom::ComputeDownscaleAndThreshold(const PushConstant& pc, IRenderCommandList& cmdList) 1798bf80f4bSopenharmony_ci{ 1808bf80f4bSopenharmony_ci RenderHandle sets[2u] {}; 1818bf80f4bSopenharmony_ci sets[0u] = binders_.globalSet0->GetDescriptorSetHandle(); 1828bf80f4bSopenharmony_ci { 1838bf80f4bSopenharmony_ci auto& binder = *binders_.downscaleAndThreshold; 1848bf80f4bSopenharmony_ci sets[1u] = binder.GetDescriptorSetHandle(); 1858bf80f4bSopenharmony_ci binder.ClearBindings(); 1868bf80f4bSopenharmony_ci 1878bf80f4bSopenharmony_ci uint32_t binding = 0; 1888bf80f4bSopenharmony_ci binder.BindImage(binding++, { targets_.tex1[0].GetHandle() }); 1898bf80f4bSopenharmony_ci binder.BindImage(binding++, { bloomInfo_.input }); 1908bf80f4bSopenharmony_ci binder.BindSampler(binding++, { samplerHandle_.GetHandle() }); 1918bf80f4bSopenharmony_ci 1928bf80f4bSopenharmony_ci cmdList.UpdateDescriptorSet(binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources()); 1938bf80f4bSopenharmony_ci } 1948bf80f4bSopenharmony_ci 1958bf80f4bSopenharmony_ci cmdList.BindPipeline(psos_.downscaleAndThreshold); 1968bf80f4bSopenharmony_ci const ShaderThreadGroup tgs = psos_.downscaleAndThresholdTGS; 1978bf80f4bSopenharmony_ci 1988bf80f4bSopenharmony_ci // bind all sets 1998bf80f4bSopenharmony_ci cmdList.BindDescriptorSets(0, sets); 2008bf80f4bSopenharmony_ci 2018bf80f4bSopenharmony_ci const auto targetSize = targets_.tex1Size[0]; 2028bf80f4bSopenharmony_ci 2038bf80f4bSopenharmony_ci LocalPostProcessPushConstantStruct uPc; 2048bf80f4bSopenharmony_ci uPc.factor = bloomParameters_; 2058bf80f4bSopenharmony_ci uPc.viewportSizeInvSize = Math::Vec4(static_cast<float>(targetSize.x), static_cast<float>(targetSize.y), 2068bf80f4bSopenharmony_ci 1.0f / static_cast<float>(targetSize.x), 1.0f / static_cast<float>(targetSize.y)); 2078bf80f4bSopenharmony_ci 2088bf80f4bSopenharmony_ci cmdList.PushConstantData(pc, arrayviewU8(uPc)); 2098bf80f4bSopenharmony_ci 2108bf80f4bSopenharmony_ci cmdList.Dispatch((targetSize.x + tgs.x - 1) / tgs.x, (targetSize.y + tgs.y - 1) / tgs.y, 1); 2118bf80f4bSopenharmony_ci} 2128bf80f4bSopenharmony_ci 2138bf80f4bSopenharmony_civoid RenderBloom::ComputeDownscale(const PushConstant& pc, IRenderCommandList& cmdList) 2148bf80f4bSopenharmony_ci{ 2158bf80f4bSopenharmony_ci cmdList.BindPipeline(psos_.downscale); 2168bf80f4bSopenharmony_ci const ShaderThreadGroup tgs = psos_.downscaleTGS; 2178bf80f4bSopenharmony_ci 2188bf80f4bSopenharmony_ci RenderHandle sets[2u] {}; 2198bf80f4bSopenharmony_ci sets[0u] = binders_.globalSet0->GetDescriptorSetHandle(); 2208bf80f4bSopenharmony_ci for (size_t i = 1; i < targets_.tex1.size(); ++i) { 2218bf80f4bSopenharmony_ci { 2228bf80f4bSopenharmony_ci auto& binder = *binders_.downscale[i]; 2238bf80f4bSopenharmony_ci sets[1u] = binder.GetDescriptorSetHandle(); 2248bf80f4bSopenharmony_ci binder.ClearBindings(); 2258bf80f4bSopenharmony_ci 2268bf80f4bSopenharmony_ci uint32_t binding = 0; 2278bf80f4bSopenharmony_ci binder.BindImage(binding++, { targets_.tex1[i].GetHandle() }); 2288bf80f4bSopenharmony_ci binder.BindImage(binding++, { targets_.tex1[i - 1].GetHandle() }); 2298bf80f4bSopenharmony_ci binder.BindSampler(binding++, { samplerHandle_.GetHandle() }); 2308bf80f4bSopenharmony_ci 2318bf80f4bSopenharmony_ci cmdList.UpdateDescriptorSet( 2328bf80f4bSopenharmony_ci binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources()); 2338bf80f4bSopenharmony_ci } 2348bf80f4bSopenharmony_ci cmdList.BindDescriptorSets(0u, sets); 2358bf80f4bSopenharmony_ci 2368bf80f4bSopenharmony_ci const auto targetSize = targets_.tex1Size[i]; 2378bf80f4bSopenharmony_ci 2388bf80f4bSopenharmony_ci LocalPostProcessPushConstantStruct uPc; 2398bf80f4bSopenharmony_ci uPc.factor = bloomParameters_; 2408bf80f4bSopenharmony_ci uPc.viewportSizeInvSize = Math::Vec4(static_cast<float>(targetSize.x), static_cast<float>(targetSize.y), 2418bf80f4bSopenharmony_ci 1.0f / static_cast<float>(targetSize.x), 1.0f / static_cast<float>(targetSize.y)); 2428bf80f4bSopenharmony_ci cmdList.PushConstantData(pc, arrayviewU8(uPc)); 2438bf80f4bSopenharmony_ci 2448bf80f4bSopenharmony_ci cmdList.Dispatch((targetSize.x + tgs.x - 1) / tgs.x, (targetSize.y + tgs.y - 1) / tgs.y, 1); 2458bf80f4bSopenharmony_ci } 2468bf80f4bSopenharmony_ci} 2478bf80f4bSopenharmony_ci 2488bf80f4bSopenharmony_civoid RenderBloom::ComputeUpscale(const PushConstant& pc, IRenderCommandList& cmdList) 2498bf80f4bSopenharmony_ci{ 2508bf80f4bSopenharmony_ci cmdList.BindPipeline(psos_.upscale); 2518bf80f4bSopenharmony_ci const ShaderThreadGroup tgs = psos_.upscaleTGS; 2528bf80f4bSopenharmony_ci 2538bf80f4bSopenharmony_ci RenderHandle sets[2u] {}; 2548bf80f4bSopenharmony_ci sets[0u] = binders_.globalSet0->GetDescriptorSetHandle(); 2558bf80f4bSopenharmony_ci 2568bf80f4bSopenharmony_ci for (size_t i = targets_.tex1.size() - 1; i != 0; --i) { 2578bf80f4bSopenharmony_ci { 2588bf80f4bSopenharmony_ci auto& binder = *binders_.upscale[i]; 2598bf80f4bSopenharmony_ci sets[1u] = binder.GetDescriptorSetHandle(); 2608bf80f4bSopenharmony_ci binder.ClearBindings(); 2618bf80f4bSopenharmony_ci 2628bf80f4bSopenharmony_ci binder.BindImage(0u, { targets_.tex1[i - 1].GetHandle() }); 2638bf80f4bSopenharmony_ci binder.BindImage(1u, { targets_.tex1[i].GetHandle() }); 2648bf80f4bSopenharmony_ci binder.BindSampler(2u, { samplerHandle_.GetHandle() }); 2658bf80f4bSopenharmony_ci 2668bf80f4bSopenharmony_ci cmdList.UpdateDescriptorSet( 2678bf80f4bSopenharmony_ci binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources()); 2688bf80f4bSopenharmony_ci } 2698bf80f4bSopenharmony_ci cmdList.BindDescriptorSets(0u, sets); 2708bf80f4bSopenharmony_ci 2718bf80f4bSopenharmony_ci const auto targetSize = targets_.tex1Size[i - 1]; 2728bf80f4bSopenharmony_ci 2738bf80f4bSopenharmony_ci LocalPostProcessPushConstantStruct uPc; 2748bf80f4bSopenharmony_ci uPc.factor = bloomParameters_; 2758bf80f4bSopenharmony_ci uPc.viewportSizeInvSize = Math::Vec4(static_cast<float>(targetSize.x), static_cast<float>(targetSize.y), 2768bf80f4bSopenharmony_ci 1.0f / static_cast<float>(targetSize.x), 1.0f / static_cast<float>(targetSize.y)); 2778bf80f4bSopenharmony_ci cmdList.PushConstantData(pc, arrayviewU8(uPc)); 2788bf80f4bSopenharmony_ci 2798bf80f4bSopenharmony_ci cmdList.Dispatch((targetSize.x + tgs.x - 1) / tgs.x, (targetSize.y + tgs.y - 1) / tgs.y, 1); 2808bf80f4bSopenharmony_ci } 2818bf80f4bSopenharmony_ci} 2828bf80f4bSopenharmony_ci 2838bf80f4bSopenharmony_civoid RenderBloom::ComputeCombine(const PushConstant& pc, IRenderCommandList& cmdList) 2848bf80f4bSopenharmony_ci{ 2858bf80f4bSopenharmony_ci cmdList.BindPipeline(psos_.combine); 2868bf80f4bSopenharmony_ci const ShaderThreadGroup tgs = psos_.combineTGS; 2878bf80f4bSopenharmony_ci 2888bf80f4bSopenharmony_ci RenderHandle sets[2u] {}; 2898bf80f4bSopenharmony_ci sets[0u] = binders_.globalSet0->GetDescriptorSetHandle(); 2908bf80f4bSopenharmony_ci { 2918bf80f4bSopenharmony_ci auto& binder = *binders_.combine; 2928bf80f4bSopenharmony_ci sets[1u] = binder.GetDescriptorSetHandle(); 2938bf80f4bSopenharmony_ci binder.ClearBindings(); 2948bf80f4bSopenharmony_ci // bind resources to set 1 2958bf80f4bSopenharmony_ci uint32_t binding = 0; 2968bf80f4bSopenharmony_ci binder.BindImage(binding++, { bloomInfo_.output }); 2978bf80f4bSopenharmony_ci binder.BindImage(binding++, { bloomInfo_.input }); 2988bf80f4bSopenharmony_ci binder.BindImage(binding++, { targets_.tex1[0].GetHandle() }); 2998bf80f4bSopenharmony_ci binder.BindSampler(binding++, { samplerHandle_.GetHandle() }); 3008bf80f4bSopenharmony_ci 3018bf80f4bSopenharmony_ci // update the descriptor set bindings for set 1 3028bf80f4bSopenharmony_ci cmdList.UpdateDescriptorSet(binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources()); 3038bf80f4bSopenharmony_ci } 3048bf80f4bSopenharmony_ci 3058bf80f4bSopenharmony_ci cmdList.BindDescriptorSets(0u, sets); 3068bf80f4bSopenharmony_ci 3078bf80f4bSopenharmony_ci const auto targetSize = baseSize_; 3088bf80f4bSopenharmony_ci 3098bf80f4bSopenharmony_ci LocalPostProcessPushConstantStruct uPc; 3108bf80f4bSopenharmony_ci uPc.factor = bloomParameters_; 3118bf80f4bSopenharmony_ci uPc.viewportSizeInvSize = Math::Vec4(static_cast<float>(targetSize.x), static_cast<float>(targetSize.y), 3128bf80f4bSopenharmony_ci 1.0f / static_cast<float>(targetSize.x), 1.0f / static_cast<float>(targetSize.y)); 3138bf80f4bSopenharmony_ci cmdList.PushConstantData(pc, arrayviewU8(uPc)); 3148bf80f4bSopenharmony_ci 3158bf80f4bSopenharmony_ci cmdList.Dispatch((targetSize.x + tgs.x - 1) / tgs.x, (targetSize.y + tgs.y - 1) / tgs.y, 1); 3168bf80f4bSopenharmony_ci} 3178bf80f4bSopenharmony_ci 3188bf80f4bSopenharmony_civoid RenderBloom::GraphicsBloom(IRenderNodeContextManager& renderNodeContextMgr, IRenderCommandList& cmdList) 3198bf80f4bSopenharmony_ci{ 3208bf80f4bSopenharmony_ci RenderPass renderPass; 3218bf80f4bSopenharmony_ci renderPass.renderPassDesc.attachmentCount = 1; 3228bf80f4bSopenharmony_ci renderPass.renderPassDesc.subpassCount = 1; 3238bf80f4bSopenharmony_ci renderPass.renderPassDesc.attachments[0].loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_DONT_CARE; 3248bf80f4bSopenharmony_ci renderPass.renderPassDesc.attachments[0].storeOp = AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE; 3258bf80f4bSopenharmony_ci 3268bf80f4bSopenharmony_ci RenderPassSubpassDesc& subpassDesc = renderPass.subpassDesc; 3278bf80f4bSopenharmony_ci subpassDesc.colorAttachmentCount = 1; 3288bf80f4bSopenharmony_ci subpassDesc.colorAttachmentIndices[0] = 0; 3298bf80f4bSopenharmony_ci 3308bf80f4bSopenharmony_ci constexpr PushConstant pc { ShaderStageFlagBits::CORE_SHADER_STAGE_FRAGMENT_BIT, 3318bf80f4bSopenharmony_ci sizeof(LocalPostProcessPushConstantStruct) }; 3328bf80f4bSopenharmony_ci 3338bf80f4bSopenharmony_ci UpdateGlobalSet(cmdList); 3348bf80f4bSopenharmony_ci if (bloomEnabled_) { 3358bf80f4bSopenharmony_ci RenderDownscaleAndThreshold(renderPass, pc, cmdList); 3368bf80f4bSopenharmony_ci RenderDownscale(renderPass, pc, cmdList); 3378bf80f4bSopenharmony_ci RenderUpscale(renderPass, pc, cmdList); 3388bf80f4bSopenharmony_ci } 3398bf80f4bSopenharmony_ci // combine (needs to be done even when bloom is disabled if node is in use 3408bf80f4bSopenharmony_ci if (RenderHandleUtil::IsValid(bloomInfo_.output.handle)) { 3418bf80f4bSopenharmony_ci RenderCombine(renderPass, pc, cmdList); 3428bf80f4bSopenharmony_ci } 3438bf80f4bSopenharmony_ci} 3448bf80f4bSopenharmony_ci 3458bf80f4bSopenharmony_civoid RenderBloom::RenderDownscaleAndThreshold( 3468bf80f4bSopenharmony_ci RenderPass& renderPass, const PushConstant& pc, IRenderCommandList& cmdList) 3478bf80f4bSopenharmony_ci{ 3488bf80f4bSopenharmony_ci const auto targetSize = targets_.tex1Size[0]; 3498bf80f4bSopenharmony_ci const ViewportDesc viewportDesc { 0, 0, static_cast<float>(targetSize.x), static_cast<float>(targetSize.y) }; 3508bf80f4bSopenharmony_ci const ScissorDesc scissorDesc = { 0, 0, targetSize.x, targetSize.y }; 3518bf80f4bSopenharmony_ci 3528bf80f4bSopenharmony_ci renderPass.renderPassDesc.attachmentHandles[0] = targets_.tex1[0].GetHandle(); 3538bf80f4bSopenharmony_ci renderPass.renderPassDesc.renderArea = { 0, 0, targetSize.x, targetSize.y }; 3548bf80f4bSopenharmony_ci cmdList.BeginRenderPass(renderPass.renderPassDesc, 0, renderPass.subpassDesc); 3558bf80f4bSopenharmony_ci 3568bf80f4bSopenharmony_ci cmdList.SetDynamicStateViewport(viewportDesc); 3578bf80f4bSopenharmony_ci cmdList.SetDynamicStateScissor(scissorDesc); 3588bf80f4bSopenharmony_ci cmdList.BindPipeline(psos_.downscaleAndThreshold); 3598bf80f4bSopenharmony_ci 3608bf80f4bSopenharmony_ci RenderHandle sets[2u] {}; 3618bf80f4bSopenharmony_ci sets[0u] = binders_.globalSet0->GetDescriptorSetHandle(); 3628bf80f4bSopenharmony_ci { 3638bf80f4bSopenharmony_ci auto& binder = *binders_.downscaleAndThreshold; 3648bf80f4bSopenharmony_ci sets[1u] = binder.GetDescriptorSetHandle(); 3658bf80f4bSopenharmony_ci binder.ClearBindings(); 3668bf80f4bSopenharmony_ci 3678bf80f4bSopenharmony_ci binder.BindImage(0u, { bloomInfo_.input }); 3688bf80f4bSopenharmony_ci binder.BindSampler(1u, { samplerHandle_.GetHandle() }); 3698bf80f4bSopenharmony_ci cmdList.UpdateDescriptorSet(binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources()); 3708bf80f4bSopenharmony_ci } 3718bf80f4bSopenharmony_ci cmdList.BindDescriptorSets(0u, sets); 3728bf80f4bSopenharmony_ci 3738bf80f4bSopenharmony_ci LocalPostProcessPushConstantStruct uPc; 3748bf80f4bSopenharmony_ci uPc.factor = bloomParameters_; 3758bf80f4bSopenharmony_ci uPc.viewportSizeInvSize = Math::Vec4(static_cast<float>(targetSize.x), static_cast<float>(targetSize.y), 3768bf80f4bSopenharmony_ci 1.0f / static_cast<float>(targetSize.x), 1.0f / static_cast<float>(targetSize.y)); 3778bf80f4bSopenharmony_ci 3788bf80f4bSopenharmony_ci cmdList.PushConstantData(pc, arrayviewU8(uPc)); 3798bf80f4bSopenharmony_ci cmdList.Draw(3u, 1u, 0u, 0u); 3808bf80f4bSopenharmony_ci cmdList.EndRenderPass(); 3818bf80f4bSopenharmony_ci} 3828bf80f4bSopenharmony_ci 3838bf80f4bSopenharmony_civoid RenderBloom::RenderDownscale(RenderPass& renderPass, const PushConstant& pc, IRenderCommandList& cmdList) 3848bf80f4bSopenharmony_ci{ 3858bf80f4bSopenharmony_ci LocalPostProcessPushConstantStruct uPc; 3868bf80f4bSopenharmony_ci uPc.factor = bloomParameters_; 3878bf80f4bSopenharmony_ci 3888bf80f4bSopenharmony_ci RenderHandle sets[2u] {}; 3898bf80f4bSopenharmony_ci sets[0u] = binders_.globalSet0->GetDescriptorSetHandle(); 3908bf80f4bSopenharmony_ci for (size_t idx = 1; idx < targets_.tex1.size(); ++idx) { 3918bf80f4bSopenharmony_ci const auto targetSize = targets_.tex1Size[idx]; 3928bf80f4bSopenharmony_ci const ViewportDesc viewportDesc { 0, 0, static_cast<float>(targetSize.x), static_cast<float>(targetSize.y) }; 3938bf80f4bSopenharmony_ci const ScissorDesc scissorDesc = { 0, 0, targetSize.x, targetSize.y }; 3948bf80f4bSopenharmony_ci 3958bf80f4bSopenharmony_ci renderPass.renderPassDesc.attachmentHandles[0] = targets_.tex1[idx].GetHandle(); 3968bf80f4bSopenharmony_ci renderPass.renderPassDesc.renderArea = { 0, 0, targetSize.x, targetSize.y }; 3978bf80f4bSopenharmony_ci cmdList.BeginRenderPass(renderPass.renderPassDesc, 0, renderPass.subpassDesc); 3988bf80f4bSopenharmony_ci 3998bf80f4bSopenharmony_ci cmdList.SetDynamicStateViewport(viewportDesc); 4008bf80f4bSopenharmony_ci cmdList.SetDynamicStateScissor(scissorDesc); 4018bf80f4bSopenharmony_ci 4028bf80f4bSopenharmony_ci cmdList.BindPipeline(psos_.downscale); 4038bf80f4bSopenharmony_ci 4048bf80f4bSopenharmony_ci { 4058bf80f4bSopenharmony_ci auto& binder = *binders_.downscale[idx]; 4068bf80f4bSopenharmony_ci sets[1u] = binder.GetDescriptorSetHandle(); 4078bf80f4bSopenharmony_ci binder.ClearBindings(); 4088bf80f4bSopenharmony_ci binder.BindImage(0u, { targets_.tex1[idx - 1].GetHandle() }); 4098bf80f4bSopenharmony_ci binder.BindSampler(1u, { samplerHandle_.GetHandle() }); 4108bf80f4bSopenharmony_ci cmdList.UpdateDescriptorSet( 4118bf80f4bSopenharmony_ci binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources()); 4128bf80f4bSopenharmony_ci } 4138bf80f4bSopenharmony_ci cmdList.BindDescriptorSets(0u, sets); 4148bf80f4bSopenharmony_ci 4158bf80f4bSopenharmony_ci uPc.viewportSizeInvSize = Math::Vec4(static_cast<float>(targetSize.x), static_cast<float>(targetSize.y), 4168bf80f4bSopenharmony_ci 1.0f / static_cast<float>(targetSize.x), 1.0f / static_cast<float>(targetSize.y)); 4178bf80f4bSopenharmony_ci 4188bf80f4bSopenharmony_ci cmdList.PushConstantData(pc, arrayviewU8(uPc)); 4198bf80f4bSopenharmony_ci cmdList.Draw(3u, 1u, 0u, 0u); 4208bf80f4bSopenharmony_ci cmdList.EndRenderPass(); 4218bf80f4bSopenharmony_ci } 4228bf80f4bSopenharmony_ci} 4238bf80f4bSopenharmony_ci 4248bf80f4bSopenharmony_civoid RenderBloom::RenderUpscale(RenderPass& renderPass, const PushConstant& pc, IRenderCommandList& cmdList) 4258bf80f4bSopenharmony_ci{ 4268bf80f4bSopenharmony_ci RenderPass renderPassUpscale = renderPass; 4278bf80f4bSopenharmony_ci renderPassUpscale.subpassDesc.inputAttachmentCount = 1; 4288bf80f4bSopenharmony_ci renderPassUpscale.subpassDesc.inputAttachmentIndices[0] = 0; 4298bf80f4bSopenharmony_ci renderPassUpscale.renderPassDesc.attachments[0].loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_DONT_CARE; 4308bf80f4bSopenharmony_ci renderPassUpscale.renderPassDesc.attachments[0].storeOp = AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE; 4318bf80f4bSopenharmony_ci 4328bf80f4bSopenharmony_ci RenderHandle sets[2u] {}; 4338bf80f4bSopenharmony_ci sets[0u] = binders_.globalSet0->GetDescriptorSetHandle(); 4348bf80f4bSopenharmony_ci PLUGIN_ASSERT(targets_.tex1.size() == targets_.tex2.size()); 4358bf80f4bSopenharmony_ci RenderHandle input; 4368bf80f4bSopenharmony_ci if (targets_.tex1.size() >= 1) { 4378bf80f4bSopenharmony_ci input = targets_.tex1[targets_.tex1.size() - 1].GetHandle(); 4388bf80f4bSopenharmony_ci } 4398bf80f4bSopenharmony_ci for (size_t idx = targets_.tex1.size() - 1; idx != 0; --idx) { 4408bf80f4bSopenharmony_ci const auto targetSize = targets_.tex1Size[idx - 1]; 4418bf80f4bSopenharmony_ci const ViewportDesc viewportDesc { 0, 0, static_cast<float>(targetSize.x), static_cast<float>(targetSize.y) }; 4428bf80f4bSopenharmony_ci const ScissorDesc scissorDesc = { 0, 0, targetSize.x, targetSize.y }; 4438bf80f4bSopenharmony_ci 4448bf80f4bSopenharmony_ci // tex2 as output 4458bf80f4bSopenharmony_ci renderPassUpscale.renderPassDesc.attachmentHandles[0] = targets_.tex2[idx - 1].GetHandle(); 4468bf80f4bSopenharmony_ci renderPassUpscale.renderPassDesc.renderArea = { 0, 0, targetSize.x, targetSize.y }; 4478bf80f4bSopenharmony_ci cmdList.BeginRenderPass(renderPassUpscale.renderPassDesc, 0, renderPassUpscale.subpassDesc); 4488bf80f4bSopenharmony_ci 4498bf80f4bSopenharmony_ci cmdList.SetDynamicStateViewport(viewportDesc); 4508bf80f4bSopenharmony_ci cmdList.SetDynamicStateScissor(scissorDesc); 4518bf80f4bSopenharmony_ci 4528bf80f4bSopenharmony_ci cmdList.BindPipeline(psos_.upscale); 4538bf80f4bSopenharmony_ci 4548bf80f4bSopenharmony_ci { 4558bf80f4bSopenharmony_ci auto& binder = *binders_.upscale[idx]; 4568bf80f4bSopenharmony_ci sets[1u] = binder.GetDescriptorSetHandle(); 4578bf80f4bSopenharmony_ci binder.ClearBindings(); 4588bf80f4bSopenharmony_ci 4598bf80f4bSopenharmony_ci uint32_t binding = 0; 4608bf80f4bSopenharmony_ci binder.BindImage(binding++, { input }); 4618bf80f4bSopenharmony_ci binder.BindImage(binding++, { targets_.tex1[idx - 1].GetHandle() }); 4628bf80f4bSopenharmony_ci binder.BindSampler(binding++, { samplerHandle_.GetHandle() }); 4638bf80f4bSopenharmony_ci cmdList.UpdateDescriptorSet( 4648bf80f4bSopenharmony_ci binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources()); 4658bf80f4bSopenharmony_ci } 4668bf80f4bSopenharmony_ci cmdList.BindDescriptorSets(0u, sets); 4678bf80f4bSopenharmony_ci LocalPostProcessPushConstantStruct uPc; 4688bf80f4bSopenharmony_ci uPc.factor = bloomParameters_; 4698bf80f4bSopenharmony_ci uPc.viewportSizeInvSize = Math::Vec4(static_cast<float>(targetSize.x), static_cast<float>(targetSize.y), 4708bf80f4bSopenharmony_ci 1.0f / static_cast<float>(targetSize.x), 1.0f / static_cast<float>(targetSize.y)); 4718bf80f4bSopenharmony_ci 4728bf80f4bSopenharmony_ci cmdList.PushConstantData(pc, arrayviewU8(uPc)); 4738bf80f4bSopenharmony_ci cmdList.Draw(3u, 1u, 0u, 0u); 4748bf80f4bSopenharmony_ci cmdList.EndRenderPass(); 4758bf80f4bSopenharmony_ci 4768bf80f4bSopenharmony_ci // next pass input 4778bf80f4bSopenharmony_ci input = renderPassUpscale.renderPassDesc.attachmentHandles[0]; 4788bf80f4bSopenharmony_ci } 4798bf80f4bSopenharmony_ci} 4808bf80f4bSopenharmony_ci 4818bf80f4bSopenharmony_civoid RenderBloom::RenderCombine(RenderPass& renderPass, const PushConstant& pc, IRenderCommandList& cmdList) 4828bf80f4bSopenharmony_ci{ 4838bf80f4bSopenharmony_ci const auto targetSize = baseSize_; 4848bf80f4bSopenharmony_ci 4858bf80f4bSopenharmony_ci renderPass.renderPassDesc.attachmentHandles[0] = bloomInfo_.output.handle; 4868bf80f4bSopenharmony_ci renderPass.renderPassDesc.renderArea = { 0, 0, targetSize.x, targetSize.y }; 4878bf80f4bSopenharmony_ci cmdList.BeginRenderPass(renderPass.renderPassDesc, 0, renderPass.subpassDesc); 4888bf80f4bSopenharmony_ci 4898bf80f4bSopenharmony_ci cmdList.SetDynamicStateViewport(baseViewportDesc_); 4908bf80f4bSopenharmony_ci cmdList.SetDynamicStateScissor(baseScissorDesc_); 4918bf80f4bSopenharmony_ci 4928bf80f4bSopenharmony_ci cmdList.BindPipeline(psos_.combine); 4938bf80f4bSopenharmony_ci 4948bf80f4bSopenharmony_ci RenderHandle sets[2u] {}; 4958bf80f4bSopenharmony_ci sets[0u] = binders_.globalSet0->GetDescriptorSetHandle(); 4968bf80f4bSopenharmony_ci { 4978bf80f4bSopenharmony_ci auto& binder = *binders_.combine; 4988bf80f4bSopenharmony_ci sets[1u] = binder.GetDescriptorSetHandle(); 4998bf80f4bSopenharmony_ci binder.ClearBindings(); 5008bf80f4bSopenharmony_ci 5018bf80f4bSopenharmony_ci uint32_t binding = 0; 5028bf80f4bSopenharmony_ci binder.BindImage(binding++, { bloomInfo_.input }); 5038bf80f4bSopenharmony_ci // tex2 handle has the final result 5048bf80f4bSopenharmony_ci binder.BindImage(binding++, { targets_.tex2[0].GetHandle() }); 5058bf80f4bSopenharmony_ci binder.BindSampler(binding++, { samplerHandle_.GetHandle() }); 5068bf80f4bSopenharmony_ci 5078bf80f4bSopenharmony_ci cmdList.UpdateDescriptorSet(binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources()); 5088bf80f4bSopenharmony_ci } 5098bf80f4bSopenharmony_ci cmdList.BindDescriptorSets(0u, sets); 5108bf80f4bSopenharmony_ci 5118bf80f4bSopenharmony_ci LocalPostProcessPushConstantStruct uPc; 5128bf80f4bSopenharmony_ci uPc.factor = bloomParameters_; 5138bf80f4bSopenharmony_ci uPc.viewportSizeInvSize = Math::Vec4(static_cast<float>(targetSize.x), static_cast<float>(targetSize.y), 5148bf80f4bSopenharmony_ci 1.0f / static_cast<float>(targetSize.x), 1.0f / static_cast<float>(targetSize.y)); 5158bf80f4bSopenharmony_ci 5168bf80f4bSopenharmony_ci cmdList.PushConstantData(pc, arrayviewU8(uPc)); 5178bf80f4bSopenharmony_ci cmdList.Draw(3u, 1u, 0u, 0u); 5188bf80f4bSopenharmony_ci cmdList.EndRenderPass(); 5198bf80f4bSopenharmony_ci} 5208bf80f4bSopenharmony_ci 5218bf80f4bSopenharmony_civoid RenderBloom::CreateTargets(IRenderNodeContextManager& renderNodeContextMgr, const Math::UVec2 baseSize) 5228bf80f4bSopenharmony_ci{ 5238bf80f4bSopenharmony_ci if (baseSize.x != baseSize_.x || baseSize.y != baseSize_.y) { 5248bf80f4bSopenharmony_ci baseSize_ = baseSize; 5258bf80f4bSopenharmony_ci 5268bf80f4bSopenharmony_ci format_ = Format::BASE_FORMAT_B10G11R11_UFLOAT_PACK32; 5278bf80f4bSopenharmony_ci ImageUsageFlags usageFlags = CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | CORE_IMAGE_USAGE_SAMPLED_BIT | 5288bf80f4bSopenharmony_ci CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; 5298bf80f4bSopenharmony_ci 5308bf80f4bSopenharmony_ci if (bloomInfo_.useCompute) { 5318bf80f4bSopenharmony_ci format_ = Format::BASE_FORMAT_R16G16B16A16_SFLOAT; // used due to GLES 5328bf80f4bSopenharmony_ci usageFlags = CORE_IMAGE_USAGE_STORAGE_BIT | CORE_IMAGE_USAGE_SAMPLED_BIT; 5338bf80f4bSopenharmony_ci } else { 5348bf80f4bSopenharmony_ci baseViewportDesc_ = { 0.0f, 0.0f, static_cast<float>(baseSize.x), static_cast<float>(baseSize.y), 0.0f, 5358bf80f4bSopenharmony_ci 1.0f }; 5368bf80f4bSopenharmony_ci baseScissorDesc_ = { 0, 0, baseSize.x, baseSize.y }; 5378bf80f4bSopenharmony_ci } 5388bf80f4bSopenharmony_ci 5398bf80f4bSopenharmony_ci // create target image 5408bf80f4bSopenharmony_ci const Math::UVec2 startTargetSize = baseSize_; 5418bf80f4bSopenharmony_ci GpuImageDesc desc { 5428bf80f4bSopenharmony_ci ImageType::CORE_IMAGE_TYPE_2D, 5438bf80f4bSopenharmony_ci ImageViewType::CORE_IMAGE_VIEW_TYPE_2D, 5448bf80f4bSopenharmony_ci format_, 5458bf80f4bSopenharmony_ci ImageTiling::CORE_IMAGE_TILING_OPTIMAL, 5468bf80f4bSopenharmony_ci usageFlags, 5478bf80f4bSopenharmony_ci MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 5488bf80f4bSopenharmony_ci 0, 5498bf80f4bSopenharmony_ci EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS | 5508bf80f4bSopenharmony_ci EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_RESET_STATE_ON_FRAME_BORDERS, 5518bf80f4bSopenharmony_ci startTargetSize.x, 5528bf80f4bSopenharmony_ci startTargetSize.y, 5538bf80f4bSopenharmony_ci 1u, 5548bf80f4bSopenharmony_ci 1u, 5558bf80f4bSopenharmony_ci 1u, 5568bf80f4bSopenharmony_ci SampleCountFlagBits::CORE_SAMPLE_COUNT_1_BIT, 5578bf80f4bSopenharmony_ci {}, 5588bf80f4bSopenharmony_ci }; 5598bf80f4bSopenharmony_ci 5608bf80f4bSopenharmony_ci auto& gpuResourceMgr = renderNodeContextMgr.GetGpuResourceManager(); 5618bf80f4bSopenharmony_ci#if (RENDER_VALIDATION_ENABLED == 1) 5628bf80f4bSopenharmony_ci const string_view nodeName = renderNodeContextMgr.GetName(); 5638bf80f4bSopenharmony_ci#endif 5648bf80f4bSopenharmony_ci for (size_t idx = 0; idx < targets_.tex1.size(); ++idx) { 5658bf80f4bSopenharmony_ci // every bloom target is half the size of the original/ previous bloom target 5668bf80f4bSopenharmony_ci desc.width /= 2u; 5678bf80f4bSopenharmony_ci desc.height /= 2u; 5688bf80f4bSopenharmony_ci desc.width = (desc.width >= 1u) ? desc.width : 1u; 5698bf80f4bSopenharmony_ci desc.height = (desc.height >= 1u) ? desc.height : 1u; 5708bf80f4bSopenharmony_ci targets_.tex1Size[idx] = Math::UVec2(desc.width, desc.height); 5718bf80f4bSopenharmony_ci#if (RENDER_VALIDATION_ENABLED == 1) 5728bf80f4bSopenharmony_ci const auto baseTargetName = nodeName + "_Bloom_" + to_string(idx); 5738bf80f4bSopenharmony_ci targets_.tex1[idx] = gpuResourceMgr.Create(baseTargetName + "_A", desc); 5748bf80f4bSopenharmony_ci if (!bloomInfo_.useCompute) { 5758bf80f4bSopenharmony_ci targets_.tex2[idx] = gpuResourceMgr.Create(baseTargetName + "_B", desc); 5768bf80f4bSopenharmony_ci } 5778bf80f4bSopenharmony_ci#else 5788bf80f4bSopenharmony_ci targets_.tex1[idx] = gpuResourceMgr.Create(targets_.tex1[idx], desc); 5798bf80f4bSopenharmony_ci if (!bloomInfo_.useCompute) { 5808bf80f4bSopenharmony_ci targets_.tex2[idx] = gpuResourceMgr.Create(targets_.tex2[idx], desc); 5818bf80f4bSopenharmony_ci } 5828bf80f4bSopenharmony_ci#endif 5838bf80f4bSopenharmony_ci } 5848bf80f4bSopenharmony_ci } 5858bf80f4bSopenharmony_ci} 5868bf80f4bSopenharmony_ci 5878bf80f4bSopenharmony_civoid RenderBloom::CreatePsos(IRenderNodeContextManager& renderNodeContextMgr) 5888bf80f4bSopenharmony_ci{ 5898bf80f4bSopenharmony_ci if (bloomInfo_.useCompute) { 5908bf80f4bSopenharmony_ci CreateComputePsos(renderNodeContextMgr); 5918bf80f4bSopenharmony_ci } else { 5928bf80f4bSopenharmony_ci CreateRenderPsos(renderNodeContextMgr); 5938bf80f4bSopenharmony_ci } 5948bf80f4bSopenharmony_ci} 5958bf80f4bSopenharmony_ci 5968bf80f4bSopenharmony_civoid RenderBloom::CreateComputePsos(IRenderNodeContextManager& renderNodeContextMgr) 5978bf80f4bSopenharmony_ci{ 5988bf80f4bSopenharmony_ci const auto& shaderMgr = renderNodeContextMgr.GetShaderManager(); 5998bf80f4bSopenharmony_ci INodeContextPsoManager& psoMgr = renderNodeContextMgr.GetPsoManager(); 6008bf80f4bSopenharmony_ci INodeContextDescriptorSetManager& dSetMgr = renderNodeContextMgr.GetDescriptorSetManager(); 6018bf80f4bSopenharmony_ci 6028bf80f4bSopenharmony_ci constexpr BASE_NS::pair<BloomConfiguration::BloomQualityType, uint32_t> configurations[] = { 6038bf80f4bSopenharmony_ci { BloomConfiguration::BloomQualityType::QUALITY_TYPE_LOW, RenderBloom::CORE_BLOOM_QUALITY_LOW }, 6048bf80f4bSopenharmony_ci { BloomConfiguration::BloomQualityType::QUALITY_TYPE_NORMAL, RenderBloom::CORE_BLOOM_QUALITY_NORMAL }, 6058bf80f4bSopenharmony_ci { BloomConfiguration::BloomQualityType::QUALITY_TYPE_HIGH, RenderBloom::CORE_BLOOM_QUALITY_HIGH } 6068bf80f4bSopenharmony_ci }; 6078bf80f4bSopenharmony_ci for (const auto& configuration : configurations) { 6088bf80f4bSopenharmony_ci { 6098bf80f4bSopenharmony_ci auto shader = shaderMgr.GetShaderHandle("rendershaders://computeshader/bloom_downscale.shader"); 6108bf80f4bSopenharmony_ci const PipelineLayout& pl = shaderMgr.GetReflectionPipelineLayout(shader); 6118bf80f4bSopenharmony_ci ShaderSpecializationConstantView specializations = shaderMgr.GetReflectionSpecialization(shader); 6128bf80f4bSopenharmony_ci const ShaderSpecializationConstantDataView specDataView { 6138bf80f4bSopenharmony_ci { specializations.constants.data(), specializations.constants.size() }, 6148bf80f4bSopenharmony_ci { &configuration.second, 1u }, 6158bf80f4bSopenharmony_ci }; 6168bf80f4bSopenharmony_ci 6178bf80f4bSopenharmony_ci psos_.downscaleHandlesCompute[configuration.first].regular = 6188bf80f4bSopenharmony_ci psoMgr.GetComputePsoHandle(shader, pl, specDataView); 6198bf80f4bSopenharmony_ci } 6208bf80f4bSopenharmony_ci { 6218bf80f4bSopenharmony_ci auto shader = shaderMgr.GetShaderHandle("rendershaders://computeshader/bloom_downscale_threshold.shader"); 6228bf80f4bSopenharmony_ci const PipelineLayout& pl = shaderMgr.GetReflectionPipelineLayout(shader); 6238bf80f4bSopenharmony_ci 6248bf80f4bSopenharmony_ci ShaderSpecializationConstantView specializations = shaderMgr.GetReflectionSpecialization(shader); 6258bf80f4bSopenharmony_ci const ShaderSpecializationConstantDataView specDataView { 6268bf80f4bSopenharmony_ci { specializations.constants.data(), specializations.constants.size() }, 6278bf80f4bSopenharmony_ci { &configuration.second, 1u }, 6288bf80f4bSopenharmony_ci }; 6298bf80f4bSopenharmony_ci psos_.downscaleHandlesCompute[configuration.first].threshold = 6308bf80f4bSopenharmony_ci psoMgr.GetComputePsoHandle(shader, pl, specDataView); 6318bf80f4bSopenharmony_ci } 6328bf80f4bSopenharmony_ci } 6338bf80f4bSopenharmony_ci 6348bf80f4bSopenharmony_ci constexpr uint32_t globalSet = 0u; 6358bf80f4bSopenharmony_ci constexpr uint32_t localSetIdx = 1u; 6368bf80f4bSopenharmony_ci // the first one creates the global set as well 6378bf80f4bSopenharmony_ci { 6388bf80f4bSopenharmony_ci const RenderHandle shaderHandle = 6398bf80f4bSopenharmony_ci shaderMgr.GetShaderHandle("rendershaders://computeshader/bloom_downscale_threshold.shader"); 6408bf80f4bSopenharmony_ci const PipelineLayout& pl = shaderMgr.GetReflectionPipelineLayout(shaderHandle); 6418bf80f4bSopenharmony_ci psos_.downscaleAndThreshold = psoMgr.GetComputePsoHandle(shaderHandle, pl, {}); 6428bf80f4bSopenharmony_ci psos_.downscaleAndThresholdTGS = shaderMgr.GetReflectionThreadGroupSize(shaderHandle); 6438bf80f4bSopenharmony_ci 6448bf80f4bSopenharmony_ci const auto& gBinds = pl.descriptorSetLayouts[globalSet].bindings; 6458bf80f4bSopenharmony_ci binders_.globalSet0 = dSetMgr.CreateDescriptorSetBinder(dSetMgr.CreateDescriptorSet(gBinds), gBinds); 6468bf80f4bSopenharmony_ci 6478bf80f4bSopenharmony_ci const auto& lBinds = pl.descriptorSetLayouts[localSetIdx].bindings; 6488bf80f4bSopenharmony_ci binders_.downscaleAndThreshold = dSetMgr.CreateDescriptorSetBinder(dSetMgr.CreateDescriptorSet(lBinds), lBinds); 6498bf80f4bSopenharmony_ci } 6508bf80f4bSopenharmony_ci { 6518bf80f4bSopenharmony_ci const RenderHandle shaderHandle = 6528bf80f4bSopenharmony_ci shaderMgr.GetShaderHandle("rendershaders://computeshader/bloom_downscale.shader"); 6538bf80f4bSopenharmony_ci const PipelineLayout& pl = shaderMgr.GetReflectionPipelineLayout(shaderHandle); 6548bf80f4bSopenharmony_ci psos_.downscale = psoMgr.GetComputePsoHandle(shaderHandle, pl, {}); 6558bf80f4bSopenharmony_ci psos_.downscaleTGS = shaderMgr.GetReflectionThreadGroupSize(shaderHandle); 6568bf80f4bSopenharmony_ci 6578bf80f4bSopenharmony_ci PLUGIN_ASSERT(binders_.downscale.size() >= TARGET_COUNT); 6588bf80f4bSopenharmony_ci const auto& binds = pl.descriptorSetLayouts[localSetIdx].bindings; 6598bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < TARGET_COUNT; ++idx) { 6608bf80f4bSopenharmony_ci binders_.downscale[idx] = dSetMgr.CreateDescriptorSetBinder(dSetMgr.CreateDescriptorSet(binds), binds); 6618bf80f4bSopenharmony_ci } 6628bf80f4bSopenharmony_ci } 6638bf80f4bSopenharmony_ci { 6648bf80f4bSopenharmony_ci const RenderHandle shaderHandle = 6658bf80f4bSopenharmony_ci shaderMgr.GetShaderHandle("rendershaders://computeshader/bloom_upscale.shader"); 6668bf80f4bSopenharmony_ci const PipelineLayout& pl = shaderMgr.GetReflectionPipelineLayout(shaderHandle); 6678bf80f4bSopenharmony_ci psos_.upscale = psoMgr.GetComputePsoHandle(shaderHandle, pl, {}); 6688bf80f4bSopenharmony_ci psos_.upscaleTGS = shaderMgr.GetReflectionThreadGroupSize(shaderHandle); 6698bf80f4bSopenharmony_ci 6708bf80f4bSopenharmony_ci PLUGIN_ASSERT(binders_.upscale.size() >= TARGET_COUNT); 6718bf80f4bSopenharmony_ci const auto& binds = pl.descriptorSetLayouts[localSetIdx].bindings; 6728bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < TARGET_COUNT; ++idx) { 6738bf80f4bSopenharmony_ci binders_.upscale[idx] = dSetMgr.CreateDescriptorSetBinder(dSetMgr.CreateDescriptorSet(binds), binds); 6748bf80f4bSopenharmony_ci } 6758bf80f4bSopenharmony_ci } 6768bf80f4bSopenharmony_ci { 6778bf80f4bSopenharmony_ci const RenderHandle shaderHandle = 6788bf80f4bSopenharmony_ci shaderMgr.GetShaderHandle("rendershaders://computeshader/bloom_combine.shader"); 6798bf80f4bSopenharmony_ci const PipelineLayout& pl = shaderMgr.GetReflectionPipelineLayout(shaderHandle); 6808bf80f4bSopenharmony_ci psos_.combine = psoMgr.GetComputePsoHandle(shaderHandle, pl, {}); 6818bf80f4bSopenharmony_ci psos_.combineTGS = shaderMgr.GetReflectionThreadGroupSize(shaderHandle); 6828bf80f4bSopenharmony_ci 6838bf80f4bSopenharmony_ci const auto& binds = pl.descriptorSetLayouts[localSetIdx].bindings; 6848bf80f4bSopenharmony_ci binders_.combine = dSetMgr.CreateDescriptorSetBinder(dSetMgr.CreateDescriptorSet(binds), binds); 6858bf80f4bSopenharmony_ci } 6868bf80f4bSopenharmony_ci} 6878bf80f4bSopenharmony_ci 6888bf80f4bSopenharmony_cistd::pair<RenderHandle, const PipelineLayout&> RenderBloom::CreateAndReflectRenderPso( 6898bf80f4bSopenharmony_ci IRenderNodeContextManager& renderNodeContextMgr, const string_view shader, const RenderPass& renderPass) 6908bf80f4bSopenharmony_ci{ 6918bf80f4bSopenharmony_ci const auto& shaderMgr = renderNodeContextMgr.GetShaderManager(); 6928bf80f4bSopenharmony_ci const RenderHandle shaderHandle = shaderMgr.GetShaderHandle(shader.data()); 6938bf80f4bSopenharmony_ci const RenderHandle graphicsStateHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(shaderHandle); 6948bf80f4bSopenharmony_ci const PipelineLayout& pl = shaderMgr.GetReflectionPipelineLayout(shaderHandle); 6958bf80f4bSopenharmony_ci 6968bf80f4bSopenharmony_ci auto& psoMgr = renderNodeContextMgr.GetPsoManager(); 6978bf80f4bSopenharmony_ci const RenderHandle pso = psoMgr.GetGraphicsPsoHandle( 6988bf80f4bSopenharmony_ci shaderHandle, graphicsStateHandle, pl, {}, {}, { DYNAMIC_STATES, countof(DYNAMIC_STATES) }); 6998bf80f4bSopenharmony_ci return { pso, pl }; 7008bf80f4bSopenharmony_ci} 7018bf80f4bSopenharmony_ci 7028bf80f4bSopenharmony_civoid RenderBloom::CreateRenderPsos(IRenderNodeContextManager& renderNodeContextMgr) 7038bf80f4bSopenharmony_ci{ 7048bf80f4bSopenharmony_ci RenderPass renderPass; 7058bf80f4bSopenharmony_ci renderPass.renderPassDesc.attachmentCount = 1; 7068bf80f4bSopenharmony_ci renderPass.renderPassDesc.attachmentHandles[0] = bloomInfo_.input.handle; 7078bf80f4bSopenharmony_ci renderPass.renderPassDesc.renderArea = { 0, 0, baseSize_.x, baseSize_.y }; 7088bf80f4bSopenharmony_ci renderPass.renderPassDesc.subpassCount = 1; 7098bf80f4bSopenharmony_ci renderPass.renderPassDesc.attachments[0].loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_DONT_CARE; 7108bf80f4bSopenharmony_ci renderPass.renderPassDesc.attachments[0].storeOp = AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE; 7118bf80f4bSopenharmony_ci 7128bf80f4bSopenharmony_ci RenderPassSubpassDesc subpassDesc = renderPass.subpassDesc; 7138bf80f4bSopenharmony_ci subpassDesc.colorAttachmentCount = 1; 7148bf80f4bSopenharmony_ci subpassDesc.colorAttachmentIndices[0] = 0; 7158bf80f4bSopenharmony_ci 7168bf80f4bSopenharmony_ci constexpr BASE_NS::pair<BloomConfiguration::BloomQualityType, uint32_t> configurations[] = { 7178bf80f4bSopenharmony_ci { BloomConfiguration::BloomQualityType::QUALITY_TYPE_LOW, RenderBloom::CORE_BLOOM_QUALITY_LOW }, 7188bf80f4bSopenharmony_ci { BloomConfiguration::BloomQualityType::QUALITY_TYPE_NORMAL, RenderBloom::CORE_BLOOM_QUALITY_NORMAL }, 7198bf80f4bSopenharmony_ci { BloomConfiguration::BloomQualityType::QUALITY_TYPE_HIGH, RenderBloom::CORE_BLOOM_QUALITY_HIGH } 7208bf80f4bSopenharmony_ci }; 7218bf80f4bSopenharmony_ci 7228bf80f4bSopenharmony_ci const IRenderNodeShaderManager& shaderMgr = renderNodeContextMgr.GetShaderManager(); 7238bf80f4bSopenharmony_ci INodeContextPsoManager& psoMgr = renderNodeContextMgr.GetPsoManager(); 7248bf80f4bSopenharmony_ci 7258bf80f4bSopenharmony_ci for (const auto& configuration : configurations) { 7268bf80f4bSopenharmony_ci { 7278bf80f4bSopenharmony_ci auto shader = shaderMgr.GetShaderHandle("rendershaders://shader/bloom_downscale.shader"); 7288bf80f4bSopenharmony_ci const PipelineLayout& pl = shaderMgr.GetReflectionPipelineLayout(shader); 7298bf80f4bSopenharmony_ci ShaderSpecializationConstantView specializations = shaderMgr.GetReflectionSpecialization(shader); 7308bf80f4bSopenharmony_ci const ShaderSpecializationConstantDataView specDataView { 7318bf80f4bSopenharmony_ci { specializations.constants.data(), specializations.constants.size() }, 7328bf80f4bSopenharmony_ci { &configuration.second, 1u }, 7338bf80f4bSopenharmony_ci }; 7348bf80f4bSopenharmony_ci const RenderHandle graphicsState = shaderMgr.GetGraphicsStateHandleByShaderHandle(shader); 7358bf80f4bSopenharmony_ci psos_.downscaleHandles[configuration.first].regular = psoMgr.GetGraphicsPsoHandle( 7368bf80f4bSopenharmony_ci shader, graphicsState, pl, {}, specDataView, { DYNAMIC_STATES, countof(DYNAMIC_STATES) }); 7378bf80f4bSopenharmony_ci } 7388bf80f4bSopenharmony_ci 7398bf80f4bSopenharmony_ci { 7408bf80f4bSopenharmony_ci auto shader = shaderMgr.GetShaderHandle("rendershaders://shader/bloom_downscale_threshold.shader"); 7418bf80f4bSopenharmony_ci const PipelineLayout& pl = shaderMgr.GetReflectionPipelineLayout(shader); 7428bf80f4bSopenharmony_ci ShaderSpecializationConstantView specializations = shaderMgr.GetReflectionSpecialization(shader); 7438bf80f4bSopenharmony_ci const ShaderSpecializationConstantDataView specDataView { 7448bf80f4bSopenharmony_ci { specializations.constants.data(), specializations.constants.size() }, 7458bf80f4bSopenharmony_ci { &configuration.second, 1u }, 7468bf80f4bSopenharmony_ci }; 7478bf80f4bSopenharmony_ci const RenderHandle graphicsState = shaderMgr.GetGraphicsStateHandleByShaderHandle(shader); 7488bf80f4bSopenharmony_ci psos_.downscaleHandles[configuration.first].threshold = psoMgr.GetGraphicsPsoHandle( 7498bf80f4bSopenharmony_ci shader, graphicsState, pl, {}, specDataView, { DYNAMIC_STATES, countof(DYNAMIC_STATES) }); 7508bf80f4bSopenharmony_ci } 7518bf80f4bSopenharmony_ci } 7528bf80f4bSopenharmony_ci 7538bf80f4bSopenharmony_ci INodeContextDescriptorSetManager& dSetMgr = renderNodeContextMgr.GetDescriptorSetManager(); 7548bf80f4bSopenharmony_ci constexpr uint32_t globalSet = 0u; 7558bf80f4bSopenharmony_ci constexpr uint32_t localSet = 1u; 7568bf80f4bSopenharmony_ci // the first one creates the global set as well 7578bf80f4bSopenharmony_ci { 7588bf80f4bSopenharmony_ci const auto [pso, pipelineLayout] = CreateAndReflectRenderPso( 7598bf80f4bSopenharmony_ci renderNodeContextMgr, "rendershaders://shader/bloom_downscale_threshold.shader", renderPass); 7608bf80f4bSopenharmony_ci psos_.downscaleAndThreshold = pso; 7618bf80f4bSopenharmony_ci 7628bf80f4bSopenharmony_ci const auto& gBinds = pipelineLayout.descriptorSetLayouts[globalSet].bindings; 7638bf80f4bSopenharmony_ci binders_.globalSet0 = dSetMgr.CreateDescriptorSetBinder(dSetMgr.CreateDescriptorSet(gBinds), gBinds); 7648bf80f4bSopenharmony_ci 7658bf80f4bSopenharmony_ci const auto& lBinds = pipelineLayout.descriptorSetLayouts[localSet].bindings; 7668bf80f4bSopenharmony_ci binders_.downscaleAndThreshold = dSetMgr.CreateDescriptorSetBinder(dSetMgr.CreateDescriptorSet(lBinds), lBinds); 7678bf80f4bSopenharmony_ci } 7688bf80f4bSopenharmony_ci { 7698bf80f4bSopenharmony_ci const auto [pso, pipelineLayout] = CreateAndReflectRenderPso( 7708bf80f4bSopenharmony_ci renderNodeContextMgr, "rendershaders://shader/bloom_downscale.shader", renderPass); 7718bf80f4bSopenharmony_ci psos_.downscale = pso; 7728bf80f4bSopenharmony_ci const auto& binds = pipelineLayout.descriptorSetLayouts[localSet].bindings; 7738bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < TARGET_COUNT; ++idx) { 7748bf80f4bSopenharmony_ci binders_.downscale[idx] = dSetMgr.CreateDescriptorSetBinder(dSetMgr.CreateDescriptorSet(binds), binds); 7758bf80f4bSopenharmony_ci } 7768bf80f4bSopenharmony_ci } 7778bf80f4bSopenharmony_ci { 7788bf80f4bSopenharmony_ci const auto [pso, pipelineLayout] = 7798bf80f4bSopenharmony_ci CreateAndReflectRenderPso(renderNodeContextMgr, "rendershaders://shader/bloom_upscale.shader", renderPass); 7808bf80f4bSopenharmony_ci psos_.upscale = pso; 7818bf80f4bSopenharmony_ci const auto& binds = pipelineLayout.descriptorSetLayouts[localSet].bindings; 7828bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < TARGET_COUNT; ++idx) { 7838bf80f4bSopenharmony_ci binders_.upscale[idx] = dSetMgr.CreateDescriptorSetBinder(dSetMgr.CreateDescriptorSet(binds), binds); 7848bf80f4bSopenharmony_ci } 7858bf80f4bSopenharmony_ci } 7868bf80f4bSopenharmony_ci { 7878bf80f4bSopenharmony_ci const auto [pso, pipelineLayout] = 7888bf80f4bSopenharmony_ci CreateAndReflectRenderPso(renderNodeContextMgr, "rendershaders://shader/bloom_combine.shader", renderPass); 7898bf80f4bSopenharmony_ci psos_.combine = pso; 7908bf80f4bSopenharmony_ci const auto& binds = pipelineLayout.descriptorSetLayouts[localSet].bindings; 7918bf80f4bSopenharmony_ci binders_.combine = dSetMgr.CreateDescriptorSetBinder(dSetMgr.CreateDescriptorSet(binds), binds); 7928bf80f4bSopenharmony_ci } 7938bf80f4bSopenharmony_ci} 7948bf80f4bSopenharmony_ciRENDER_END_NAMESPACE() 795