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_copy.h" 178bf80f4bSopenharmony_ci 188bf80f4bSopenharmony_ci#include <render/device/intf_gpu_resource_manager.h> 198bf80f4bSopenharmony_ci#include <render/device/intf_shader_manager.h> 208bf80f4bSopenharmony_ci#include <render/device/pipeline_layout_desc.h> 218bf80f4bSopenharmony_ci#include <render/device/pipeline_state_desc.h> 228bf80f4bSopenharmony_ci#include <render/namespace.h> 238bf80f4bSopenharmony_ci#include <render/nodecontext/intf_node_context_descriptor_set_manager.h> 248bf80f4bSopenharmony_ci#include <render/nodecontext/intf_node_context_pso_manager.h> 258bf80f4bSopenharmony_ci#include <render/nodecontext/intf_pipeline_descriptor_set_binder.h> 268bf80f4bSopenharmony_ci#include <render/nodecontext/intf_render_command_list.h> 278bf80f4bSopenharmony_ci#include <render/nodecontext/intf_render_node_context_manager.h> 288bf80f4bSopenharmony_ci#include <render/nodecontext/intf_render_node_util.h> 298bf80f4bSopenharmony_ci 308bf80f4bSopenharmony_ci#include "default_engine_constants.h" 318bf80f4bSopenharmony_ci#include "device/gpu_resource_handle_util.h" 328bf80f4bSopenharmony_ci#include "util/log.h" 338bf80f4bSopenharmony_ci 348bf80f4bSopenharmony_ci// shaders 358bf80f4bSopenharmony_ci#include <render/shaders/common/render_post_process_structs_common.h> 368bf80f4bSopenharmony_ci 378bf80f4bSopenharmony_ciusing namespace BASE_NS; 388bf80f4bSopenharmony_ci 398bf80f4bSopenharmony_ciRENDER_BEGIN_NAMESPACE() 408bf80f4bSopenharmony_cinamespace { 418bf80f4bSopenharmony_ciconstexpr DynamicStateEnum DYNAMIC_STATES[] = { CORE_DYNAMIC_STATE_ENUM_VIEWPORT, CORE_DYNAMIC_STATE_ENUM_SCISSOR }; 428bf80f4bSopenharmony_ci 438bf80f4bSopenharmony_ciRenderPass CreateRenderPass(const IRenderNodeGpuResourceManager& gpuResourceMgr, const RenderHandle input) 448bf80f4bSopenharmony_ci{ 458bf80f4bSopenharmony_ci const GpuImageDesc desc = gpuResourceMgr.GetImageDescriptor(input); 468bf80f4bSopenharmony_ci RenderPass rp; 478bf80f4bSopenharmony_ci rp.renderPassDesc.attachmentCount = 1u; 488bf80f4bSopenharmony_ci rp.renderPassDesc.attachmentHandles[0u] = input; 498bf80f4bSopenharmony_ci rp.renderPassDesc.attachments[0u].loadOp = AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_DONT_CARE; 508bf80f4bSopenharmony_ci rp.renderPassDesc.attachments[0u].storeOp = AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE; 518bf80f4bSopenharmony_ci rp.renderPassDesc.renderArea = { 0, 0, desc.width, desc.height }; 528bf80f4bSopenharmony_ci 538bf80f4bSopenharmony_ci rp.renderPassDesc.subpassCount = 1u; 548bf80f4bSopenharmony_ci rp.subpassDesc.colorAttachmentCount = 1u; 558bf80f4bSopenharmony_ci rp.subpassDesc.colorAttachmentIndices[0u] = 0u; 568bf80f4bSopenharmony_ci rp.subpassStartIndex = 0u; 578bf80f4bSopenharmony_ci return rp; 588bf80f4bSopenharmony_ci} 598bf80f4bSopenharmony_ci 608bf80f4bSopenharmony_ciRenderHandle CreatePso( 618bf80f4bSopenharmony_ci IRenderNodeContextManager& renderNodeContextMgr, const RenderHandle& shader, const PipelineLayout& pipelineLayout) 628bf80f4bSopenharmony_ci{ 638bf80f4bSopenharmony_ci auto& psoMgr = renderNodeContextMgr.GetPsoManager(); 648bf80f4bSopenharmony_ci const auto& shaderMgr = renderNodeContextMgr.GetShaderManager(); 658bf80f4bSopenharmony_ci const RenderHandle graphicsStateHandle = shaderMgr.GetGraphicsStateHandleByShaderHandle(shader); 668bf80f4bSopenharmony_ci return psoMgr.GetGraphicsPsoHandle( 678bf80f4bSopenharmony_ci shader, graphicsStateHandle, pipelineLayout, {}, {}, { DYNAMIC_STATES, countof(DYNAMIC_STATES) }); 688bf80f4bSopenharmony_ci} 698bf80f4bSopenharmony_ci} // namespace 708bf80f4bSopenharmony_ci 718bf80f4bSopenharmony_civoid RenderCopy::Init(IRenderNodeContextManager& renderNodeContextMgr, const CopyInfo& copyInfo) 728bf80f4bSopenharmony_ci{ 738bf80f4bSopenharmony_ci copyInfo_ = copyInfo; 748bf80f4bSopenharmony_ci const IRenderNodeShaderManager& shaderMgr = renderNodeContextMgr.GetShaderManager(); 758bf80f4bSopenharmony_ci { 768bf80f4bSopenharmony_ci renderData_ = {}; 778bf80f4bSopenharmony_ci renderData_.shader = shaderMgr.GetShaderHandle("rendershaders://shader/fullscreen_copy.shader"); 788bf80f4bSopenharmony_ci renderData_.pipelineLayout = shaderMgr.GetReflectionPipelineLayout(renderData_.shader); 798bf80f4bSopenharmony_ci renderData_.sampler = renderNodeContextMgr.GetGpuResourceManager().GetSamplerHandle( 808bf80f4bSopenharmony_ci DefaultEngineGpuResourceConstants::CORE_DEFAULT_SAMPLER_LINEAR_CLAMP); 818bf80f4bSopenharmony_ci 828bf80f4bSopenharmony_ci renderData_.shaderLayer = shaderMgr.GetShaderHandle("rendershaders://shader/fullscreen_copy_layer.shader"); 838bf80f4bSopenharmony_ci renderData_.pipelineLayoutLayer = shaderMgr.GetReflectionPipelineLayout(renderData_.shaderLayer); 848bf80f4bSopenharmony_ci } 858bf80f4bSopenharmony_ci { 868bf80f4bSopenharmony_ci // single binder for both 878bf80f4bSopenharmony_ci INodeContextDescriptorSetManager& descriptorSetMgr = renderNodeContextMgr.GetDescriptorSetManager(); 888bf80f4bSopenharmony_ci const auto& bindings = renderData_.pipelineLayout.descriptorSetLayouts[0U].bindings; 898bf80f4bSopenharmony_ci const RenderHandle descHandle = descriptorSetMgr.CreateDescriptorSet(bindings); 908bf80f4bSopenharmony_ci binder_ = descriptorSetMgr.CreateDescriptorSetBinder(descHandle, bindings); 918bf80f4bSopenharmony_ci } 928bf80f4bSopenharmony_ci} 938bf80f4bSopenharmony_ci 948bf80f4bSopenharmony_civoid RenderCopy::PreExecute(IRenderNodeContextManager& renderNodeContextMgr, const CopyInfo& copyInfo) 958bf80f4bSopenharmony_ci{ 968bf80f4bSopenharmony_ci copyInfo_ = copyInfo; 978bf80f4bSopenharmony_ci} 988bf80f4bSopenharmony_ci 998bf80f4bSopenharmony_civoid RenderCopy::Execute(IRenderNodeContextManager& renderNodeContextMgr, IRenderCommandList& cmdList) 1008bf80f4bSopenharmony_ci{ 1018bf80f4bSopenharmony_ci // extra blit from input to ouput 1028bf80f4bSopenharmony_ci if (RenderHandleUtil::IsGpuImage(copyInfo_.input.handle) && RenderHandleUtil::IsGpuImage(copyInfo_.output.handle) && 1038bf80f4bSopenharmony_ci binder_) { 1048bf80f4bSopenharmony_ci auto& gpuResourceMgr = renderNodeContextMgr.GetGpuResourceManager(); 1058bf80f4bSopenharmony_ci 1068bf80f4bSopenharmony_ci auto renderPass = CreateRenderPass(gpuResourceMgr, copyInfo_.output.handle); 1078bf80f4bSopenharmony_ci RenderHandle pso; 1088bf80f4bSopenharmony_ci if (copyInfo_.copyType == CopyType::LAYER_COPY) { 1098bf80f4bSopenharmony_ci if (!RenderHandleUtil::IsValid(renderData_.psoLayer)) { 1108bf80f4bSopenharmony_ci renderData_.psoLayer = 1118bf80f4bSopenharmony_ci CreatePso(renderNodeContextMgr, renderData_.shaderLayer, renderData_.pipelineLayoutLayer); 1128bf80f4bSopenharmony_ci } 1138bf80f4bSopenharmony_ci pso = renderData_.psoLayer; 1148bf80f4bSopenharmony_ci } else { 1158bf80f4bSopenharmony_ci if (!RenderHandleUtil::IsValid(renderData_.pso)) { 1168bf80f4bSopenharmony_ci renderData_.pso = CreatePso(renderNodeContextMgr, renderData_.shader, renderData_.pipelineLayout); 1178bf80f4bSopenharmony_ci } 1188bf80f4bSopenharmony_ci pso = renderData_.pso; 1198bf80f4bSopenharmony_ci } 1208bf80f4bSopenharmony_ci 1218bf80f4bSopenharmony_ci cmdList.BeginRenderPass(renderPass.renderPassDesc, renderPass.subpassStartIndex, renderPass.subpassDesc); 1228bf80f4bSopenharmony_ci cmdList.BindPipeline(pso); 1238bf80f4bSopenharmony_ci 1248bf80f4bSopenharmony_ci { 1258bf80f4bSopenharmony_ci auto& binder = *binder_; 1268bf80f4bSopenharmony_ci binder.ClearBindings(); 1278bf80f4bSopenharmony_ci uint32_t binding = 0u; 1288bf80f4bSopenharmony_ci binder.BindSampler( 1298bf80f4bSopenharmony_ci binding, RenderHandleUtil::IsValid(copyInfo_.sampler) ? copyInfo_.sampler : renderData_.sampler); 1308bf80f4bSopenharmony_ci binder.BindImage(++binding, copyInfo_.input); 1318bf80f4bSopenharmony_ci cmdList.UpdateDescriptorSet( 1328bf80f4bSopenharmony_ci binder.GetDescriptorSetHandle(), binder.GetDescriptorSetLayoutBindingResources()); 1338bf80f4bSopenharmony_ci cmdList.BindDescriptorSet(0u, binder.GetDescriptorSetHandle()); 1348bf80f4bSopenharmony_ci } 1358bf80f4bSopenharmony_ci 1368bf80f4bSopenharmony_ci // dynamic state 1378bf80f4bSopenharmony_ci const IRenderNodeUtil& renderNodeUtil = renderNodeContextMgr.GetRenderNodeUtil(); 1388bf80f4bSopenharmony_ci const ViewportDesc viewportDesc = renderNodeUtil.CreateDefaultViewport(renderPass); 1398bf80f4bSopenharmony_ci const ScissorDesc scissorDesc = renderNodeUtil.CreateDefaultScissor(renderPass); 1408bf80f4bSopenharmony_ci cmdList.SetDynamicStateViewport(viewportDesc); 1418bf80f4bSopenharmony_ci cmdList.SetDynamicStateScissor(scissorDesc); 1428bf80f4bSopenharmony_ci 1438bf80f4bSopenharmony_ci const auto& pl = 1448bf80f4bSopenharmony_ci (copyInfo_.copyType == CopyType::LAYER_COPY) ? renderData_.pipelineLayoutLayer : renderData_.pipelineLayout; 1458bf80f4bSopenharmony_ci if (pl.pushConstant.byteSize > 0) { 1468bf80f4bSopenharmony_ci const float fWidth = static_cast<float>(renderPass.renderPassDesc.renderArea.extentWidth); 1478bf80f4bSopenharmony_ci const float fHeight = static_cast<float>(renderPass.renderPassDesc.renderArea.extentHeight); 1488bf80f4bSopenharmony_ci const LocalPostProcessPushConstantStruct pc { { fWidth, fHeight, 1.0f / fWidth, 1.0f / fHeight }, 1498bf80f4bSopenharmony_ci { static_cast<float>(copyInfo_.input.layer), 0.0f, 0.0f, 0.0f } }; 1508bf80f4bSopenharmony_ci cmdList.PushConstantData(pl.pushConstant, arrayviewU8(pc)); 1518bf80f4bSopenharmony_ci } 1528bf80f4bSopenharmony_ci 1538bf80f4bSopenharmony_ci cmdList.Draw(3u, 1u, 0u, 0u); 1548bf80f4bSopenharmony_ci cmdList.EndRenderPass(); 1558bf80f4bSopenharmony_ci } 1568bf80f4bSopenharmony_ci} 1578bf80f4bSopenharmony_ci 1588bf80f4bSopenharmony_ciDescriptorCounts RenderCopy::GetDescriptorCounts() const 1598bf80f4bSopenharmony_ci{ 1608bf80f4bSopenharmony_ci // prepare only for a single copy operation per frame 1618bf80f4bSopenharmony_ci return DescriptorCounts { { 1628bf80f4bSopenharmony_ci { CORE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1U }, 1638bf80f4bSopenharmony_ci { CORE_DESCRIPTOR_TYPE_SAMPLER, 1U }, 1648bf80f4bSopenharmony_ci } }; 1658bf80f4bSopenharmony_ci} 1668bf80f4bSopenharmony_ciRENDER_END_NAMESPACE() 167