• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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_node_fullscreen_generic.h"
17 
18 #include <base/math/mathf.h>
19 #include <render/datastore/intf_render_data_store_manager.h>
20 #include <render/datastore/intf_render_data_store_pod.h>
21 #include <render/device/intf_gpu_resource_manager.h>
22 #include <render/device/intf_shader_manager.h>
23 #include <render/device/pipeline_layout_desc.h>
24 #include <render/device/pipeline_state_desc.h>
25 #include <render/namespace.h>
26 #include <render/nodecontext/intf_node_context_descriptor_set_manager.h>
27 #include <render/nodecontext/intf_node_context_pso_manager.h>
28 #include <render/nodecontext/intf_pipeline_descriptor_set_binder.h>
29 #include <render/nodecontext/intf_render_command_list.h>
30 #include <render/nodecontext/intf_render_node_context_manager.h>
31 #include <render/nodecontext/intf_render_node_parser_util.h>
32 #include <render/nodecontext/intf_render_node_util.h>
33 
34 #include "util/log.h"
35 
36 using namespace BASE_NS;
37 
RENDER_BEGIN_NAMESPACE()38 RENDER_BEGIN_NAMESPACE()
39 void RenderNodeFullscreenGeneric::InitNode(IRenderNodeContextManager& renderNodeContextMgr)
40 {
41     renderNodeContextMgr_ = &renderNodeContextMgr;
42     ParseRenderNodeInputs();
43 
44     useDataStoreShaderSpecialization_ = !jsonInputs_.renderDataStoreSpecialization.dataStoreName.empty();
45 
46     const IRenderNodeShaderManager& shaderMgr = renderNodeContextMgr_->GetShaderManager();
47     if (!shaderMgr.IsValid(shader_)) {
48         PLUGIN_LOG_E("RenderNodeFullscreenGeneric needs a valid shader handle");
49     }
50 
51     if (useDataStoreShaderSpecialization_) {
52         const ShaderSpecilizationConstantView sscv = shaderMgr.GetReflectionSpecialization(shader_);
53         shaderSpecializationData_.constants.resize(sscv.constants.size());
54         shaderSpecializationData_.data.resize(sscv.constants.size());
55         for (size_t idx = 0; idx < shaderSpecializationData_.constants.size(); ++idx) {
56             shaderSpecializationData_.constants[idx] = sscv.constants[idx];
57             shaderSpecializationData_.data[idx] = ~0u;
58         }
59         useDataStoreShaderSpecialization_ = !sscv.constants.empty();
60     }
61 
62     const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
63     const RenderHandle graphicsState = shaderMgr.GetGraphicsStateHandleByShaderHandle(shader_);
64     pipelineLayout_ = renderNodeUtil.CreatePipelineLayout(shader_);
65     constexpr DynamicStateFlags dynamicStateFlags =
66         DynamicStateFlagBits::CORE_DYNAMIC_STATE_VIEWPORT | DynamicStateFlagBits::CORE_DYNAMIC_STATE_SCISSOR;
67     psoHandle_ = renderNodeContextMgr.GetPsoManager().GetGraphicsPsoHandle(
68         shader_, graphicsState, pipelineLayout_, {}, {}, dynamicStateFlags);
69 
70     {
71         const DescriptorCounts dc = renderNodeUtil.GetDescriptorCounts(pipelineLayout_);
72         renderNodeContextMgr.GetDescriptorSetManager().ResetAndReserve(dc);
73     }
74 
75     pipelineDescriptorSetBinder_ = renderNodeUtil.CreatePipelineDescriptorSetBinder(pipelineLayout_);
76     renderNodeUtil.BindResourcesToBinder(inputResources_, *pipelineDescriptorSetBinder_);
77 
78     useDataStorePushConstant_ = (pipelineLayout_.pushConstant.byteSize > 0) &&
79                                 (!jsonInputs_.renderDataStore.dataStoreName.empty()) &&
80                                 (!jsonInputs_.renderDataStore.configurationName.empty());
81 }
82 
PreExecuteFrame()83 void RenderNodeFullscreenGeneric::PreExecuteFrame()
84 {
85     // re-create needed gpu resources
86 }
87 
ExecuteFrame(IRenderCommandList & cmdList)88 void RenderNodeFullscreenGeneric::ExecuteFrame(IRenderCommandList& cmdList)
89 {
90     if (!Render::RenderHandleUtil::IsValid(shader_)) {
91         return;
92     }
93 
94     const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
95     if (jsonInputs_.hasChangeableRenderPassHandles) {
96         inputRenderPass_ = renderNodeUtil.CreateInputRenderPass(jsonInputs_.renderPass);
97     }
98     if (jsonInputs_.hasChangeableResourceHandles) {
99         inputResources_ = renderNodeUtil.CreateInputResources(jsonInputs_.resources);
100         renderNodeUtil.BindResourcesToBinder(inputResources_, *pipelineDescriptorSetBinder_);
101     }
102 
103     const RenderPass renderPass = renderNodeUtil.CreateRenderPass(inputRenderPass_);
104     const ViewportDesc viewportDesc = renderNodeUtil.CreateDefaultViewport(renderPass);
105     const ScissorDesc scissorDesc = renderNodeUtil.CreateDefaultScissor(renderPass);
106 
107     const auto setIndices = pipelineDescriptorSetBinder_->GetSetIndices();
108     for (auto refIndex : setIndices) {
109         const auto descHandle = pipelineDescriptorSetBinder_->GetDescriptorSetHandle(refIndex);
110         const auto bindings = pipelineDescriptorSetBinder_->GetDescriptorSetLayoutBindingResources(refIndex);
111         cmdList.UpdateDescriptorSet(descHandle, bindings);
112     }
113 #if (RENDER_VALIDATION_ENABLED == 1)
114     if (!pipelineDescriptorSetBinder_->GetPipelineDescriptorSetLayoutBindingValidity()) {
115         PLUGIN_LOG_E("RenderNodeFullscreenGeneric: bindings missing (RN: %s)", renderNodeContextMgr_->GetName().data());
116     }
117 #endif
118 
119     cmdList.BeginRenderPass(renderPass.renderPassDesc, renderPass.subpassStartIndex, renderPass.subpassDesc);
120 
121     const RenderHandle psoHandle = GetPsoHandle(*renderNodeContextMgr_);
122     cmdList.BindPipeline(psoHandle);
123 
124     // bind all sets
125     cmdList.BindDescriptorSets(0u, pipelineDescriptorSetBinder_->GetDescriptorSetHandles());
126 
127     // dynamic state
128     cmdList.SetDynamicStateViewport(viewportDesc);
129     cmdList.SetDynamicStateScissor(scissorDesc);
130 
131     // push constants
132     if (useDataStorePushConstant_) {
133         const auto& renderDataStoreMgr = renderNodeContextMgr_->GetRenderDataStoreManager();
134         const auto dataStore = static_cast<IRenderDataStorePod const*>(
135             renderDataStoreMgr.GetRenderDataStore(jsonInputs_.renderDataStore.dataStoreName));
136         if (dataStore) {
137             const auto dataView = dataStore->Get(jsonInputs_.renderDataStore.configurationName);
138             if (!dataView.empty()) {
139                 cmdList.PushConstant(pipelineLayout_.pushConstant, dataView.data());
140             }
141         }
142     }
143 
144     cmdList.Draw(3u, 1u, 0u, 0u); // vertex count, instance count, first vertex, first instance
145     cmdList.EndRenderPass();
146 }
147 
GetPsoHandle(IRenderNodeContextManager & renderNodeContextMgr)148 RenderHandle RenderNodeFullscreenGeneric::GetPsoHandle(IRenderNodeContextManager& renderNodeContextMgr)
149 {
150     if (useDataStoreShaderSpecialization_) {
151         const auto& renderDataStoreMgr = renderNodeContextMgr.GetRenderDataStoreManager();
152         const auto dataStore = static_cast<IRenderDataStorePod const*>(
153             renderDataStoreMgr.GetRenderDataStore(jsonInputs_.renderDataStoreSpecialization.dataStoreName));
154         if (dataStore) {
155             const auto dataView = dataStore->Get(jsonInputs_.renderDataStoreSpecialization.configurationName);
156             if (dataView.data() && (dataView.size_bytes() == sizeof(ShaderSpecializationRenderPod))) {
157                 const auto* spec = reinterpret_cast<const ShaderSpecializationRenderPod*>(dataView.data());
158                 bool valuesChanged = false;
159                 const uint32_t specializationCount = Math::min(
160                     Math::min(spec->specializationConstantCount, (uint32_t)shaderSpecializationData_.constants.size()),
161                     ShaderSpecializationRenderPod::MAX_SPECIALIZATION_CONSTANT_COUNT);
162                 for (uint32_t idx = 0; idx < specializationCount; ++idx) {
163                     const auto& ref = shaderSpecializationData_.constants[idx];
164                     const uint32_t constantId = ref.offset / sizeof(uint32_t);
165                     const uint32_t specId = ref.id;
166                     if (specId < ShaderSpecializationRenderPod::MAX_SPECIALIZATION_CONSTANT_COUNT) {
167                         if (shaderSpecializationData_.data[constantId] != spec->specializationFlags[specId].value) {
168                             shaderSpecializationData_.data[constantId] = spec->specializationFlags[specId].value;
169                             valuesChanged = true;
170                         }
171                     }
172                 }
173                 if (valuesChanged) {
174                     constexpr DynamicStateFlags dynamicStateFlags = DynamicStateFlagBits::CORE_DYNAMIC_STATE_VIEWPORT |
175                                                                     DynamicStateFlagBits::CORE_DYNAMIC_STATE_SCISSOR;
176                     const ShaderSpecializationConstantDataView specialization {
177                         { shaderSpecializationData_.constants.data(), specializationCount },
178                         { shaderSpecializationData_.data.data(), specializationCount }
179                     };
180                     const RenderHandle graphicsState =
181                         renderNodeContextMgr_->GetShaderManager().GetGraphicsStateHandleByShaderHandle(shader_);
182                     psoHandle_ = renderNodeContextMgr.GetPsoManager().GetGraphicsPsoHandle(
183                         shader_, graphicsState, pipelineLayout_, {}, specialization, dynamicStateFlags);
184                 }
185             } else {
186                 const string logName = "RenderNodeFullscreenGeneric_ShaderSpecialization" +
187                                        string(jsonInputs_.renderDataStoreSpecialization.configurationName);
188                 PLUGIN_LOG_ONCE_E(logName.c_str(),
189                     "RenderNodeFullscreenGeneric shader specilization render data store size mismatch, name: %s, "
190                     "size:%u, podsize%u",
191                     jsonInputs_.renderDataStoreSpecialization.configurationName.c_str(),
192                     static_cast<uint32_t>(sizeof(ShaderSpecializationRenderPod)),
193                     static_cast<uint32_t>(dataView.size_bytes()));
194             }
195         }
196     }
197     return psoHandle_;
198 }
199 
ParseRenderNodeInputs()200 void RenderNodeFullscreenGeneric::ParseRenderNodeInputs()
201 {
202     const IRenderNodeParserUtil& parserUtil = renderNodeContextMgr_->GetRenderNodeParserUtil();
203     const auto jsonVal = renderNodeContextMgr_->GetNodeJson();
204     jsonInputs_.renderPass = parserUtil.GetInputRenderPass(jsonVal, "renderPass");
205     jsonInputs_.resources = parserUtil.GetInputResources(jsonVal, "resources");
206     jsonInputs_.renderDataStore = parserUtil.GetRenderDataStore(jsonVal, "renderDataStore");
207     jsonInputs_.renderDataStoreSpecialization =
208         parserUtil.GetRenderDataStore(jsonVal, "renderDataStoreShaderSpecialization");
209 
210     const auto shaderName = parserUtil.GetStringValue(jsonVal, "shader");
211     const IRenderNodeShaderManager& shaderMgr = renderNodeContextMgr_->GetShaderManager();
212     shader_ = shaderMgr.GetShaderHandle(shaderName);
213 
214     const auto& renderNodeUtil = renderNodeContextMgr_->GetRenderNodeUtil();
215     inputRenderPass_ = renderNodeUtil.CreateInputRenderPass(jsonInputs_.renderPass);
216     inputResources_ = renderNodeUtil.CreateInputResources(jsonInputs_.resources);
217 
218     jsonInputs_.hasChangeableRenderPassHandles = renderNodeUtil.HasChangeableResources(jsonInputs_.renderPass);
219     jsonInputs_.hasChangeableResourceHandles = renderNodeUtil.HasChangeableResources(jsonInputs_.resources);
220 }
221 
222 // for plugin / factory interface
Create()223 IRenderNode* RenderNodeFullscreenGeneric::Create()
224 {
225     return new RenderNodeFullscreenGeneric();
226 }
227 
Destroy(IRenderNode * instance)228 void RenderNodeFullscreenGeneric::Destroy(IRenderNode* instance)
229 {
230     delete static_cast<RenderNodeFullscreenGeneric*>(instance);
231 }
232 RENDER_END_NAMESPACE()
233