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 "util/render_util.h"
17
18 #include <3d/intf_graphics_context.h>
19 #include <3d/render/intf_render_data_store_default_camera.h>
20 #include <core/intf_engine.h>
21 #include <core/json/json.h>
22 #include <core/namespace.h>
23 #include <render/device/intf_device.h>
24 #include <render/device/intf_gpu_resource_manager.h>
25 #include <render/intf_render_context.h>
26 #include <render/render_data_structures.h>
27
28 CORE3D_BEGIN_NAMESPACE()
29 using namespace BASE_NS;
30 using namespace CORE_NS;
31 using namespace RENDER_NS;
32
33 namespace {
34 constexpr const string_view SCENE_STR = "3drendernodegraphs://core3d_rng_scene.rng";
35 constexpr const string_view CAM_SCENE_LWRP_STR = "3drendernodegraphs://core3d_rng_cam_scene_lwrp.rng";
36 constexpr const string_view CAM_SCENE_LWRP_MSAA_STR = "3drendernodegraphs://core3d_rng_cam_scene_lwrp_msaa.rng";
37 constexpr const string_view CAM_SCENE_LWRP_MSAA_GLES_STR =
38 "3drendernodegraphs://core3d_rng_cam_scene_lwrp_msaa_gles.rng";
39 constexpr const string_view CAM_SCENE_HDRP_STR = "3drendernodegraphs://core3d_rng_cam_scene_hdrp.rng";
40 constexpr const string_view CAM_SCENE_HDRP_MSAA_STR = "3drendernodegraphs://core3d_rng_cam_scene_hdrp_msaa.rng";
41 constexpr const string_view CAM_SCENE_REFLECTION_STR = "3drendernodegraphs://core3d_rng_reflection_cam_scene.rng";
42 constexpr const string_view CAM_SCENE_PRE_PASS_STR = "3drendernodegraphs://core3d_rng_cam_scene_pre_pass.rng";
43 constexpr const string_view CAM_SCENE_DEFERRED_STR = "3drendernodegraphs://core3d_rng_cam_scene_deferred.rng";
44
LoadRenderNodeGraph(IRenderNodeGraphLoader & rngLoader,const string_view rng)45 RenderNodeGraphDesc LoadRenderNodeGraph(IRenderNodeGraphLoader& rngLoader, const string_view rng)
46 {
47 IRenderNodeGraphLoader::LoadResult lr = rngLoader.Load(rng);
48 if (!lr.success) {
49 CORE_LOG_E("error loading render node graph: %s - error: %s", rng.data(), lr.error.data());
50 }
51 return lr.desc;
52 }
53 } // namespace
54
RenderUtil(IGraphicsContext & graphicsContext)55 RenderUtil::RenderUtil(IGraphicsContext& graphicsContext)
56 : context_(graphicsContext.GetRenderContext()), backendType_(context_.GetDevice().GetBackendType())
57 {
58 InitRenderNodeGraphs();
59 }
60
InitRenderNodeGraphs()61 void RenderUtil::InitRenderNodeGraphs()
62 {
63 IRenderNodeGraphManager& rngm = context_.GetRenderNodeGraphManager();
64 IRenderNodeGraphLoader& rngl = rngm.GetRenderNodeGraphLoader();
65
66 rngdScene_ = LoadRenderNodeGraph(rngl, SCENE_STR);
67 rngdCamLwrp_ = LoadRenderNodeGraph(rngl, CAM_SCENE_LWRP_STR);
68 rngdCamLwrpMsaa_ = LoadRenderNodeGraph(rngl, CAM_SCENE_LWRP_MSAA_STR);
69 rngdCamLwrpMsaaGles_ = LoadRenderNodeGraph(rngl, CAM_SCENE_LWRP_MSAA_GLES_STR);
70 rngdCamHdr_ = LoadRenderNodeGraph(rngl, CAM_SCENE_HDRP_STR);
71 rngdCamHdrMsaa_ = LoadRenderNodeGraph(rngl, CAM_SCENE_HDRP_MSAA_STR);
72 rngdReflCam_ = LoadRenderNodeGraph(rngl, CAM_SCENE_REFLECTION_STR);
73 rngdCamPrePass_ = LoadRenderNodeGraph(rngl, CAM_SCENE_PRE_PASS_STR);
74
75 rngdDeferred_ = LoadRenderNodeGraph(rngl, CAM_SCENE_DEFERRED_STR);
76 }
77
SelectBaseDesc(const RenderCamera & renderCamera) const78 RenderNodeGraphDesc RenderUtil::SelectBaseDesc(const RenderCamera& renderCamera) const
79 {
80 RenderNodeGraphDesc desc;
81 if (!renderCamera.customRenderNodeGraphFile.empty()) {
82 // custom render node graph file given which is patched
83 IRenderNodeGraphLoader& rngl = context_.GetRenderNodeGraphManager().GetRenderNodeGraphLoader();
84 desc = LoadRenderNodeGraph(rngl, renderCamera.customRenderNodeGraphFile);
85 } else {
86 if (renderCamera.flags & RenderCamera::CAMERA_FLAG_REFLECTION_BIT) {
87 desc = rngdReflCam_;
88 } else if (renderCamera.flags & RenderCamera::CAMERA_FLAG_OPAQUE_BIT) {
89 desc = rngdCamPrePass_;
90 } else {
91 if (renderCamera.renderPipelineType == RenderCamera::RenderPipelineType::DEFERRED) {
92 desc = rngdDeferred_;
93 } else {
94 if (renderCamera.flags & RenderCamera::CAMERA_FLAG_MSAA_BIT) {
95 // NOTE: check for optimal GL(ES) render node graph if backbuffer is multisampled
96 if (renderCamera.renderPipelineType != RenderCamera::RenderPipelineType::LIGHT_FORWARD) {
97 desc = rngdCamHdrMsaa_;
98 } else if (backendType_ == DeviceBackendType::VULKAN) {
99 desc = rngdCamLwrpMsaa_;
100 } else {
101 const auto& gpuResourceMgr = context_.GetDevice().GetGpuResourceManager();
102 const RenderHandleReference imageHandle =
103 gpuResourceMgr.GetImageHandle("CORE_DEFAULT_BACKBUFFER");
104 const GpuImageDesc imageDesc = gpuResourceMgr.GetImageDescriptor(imageHandle);
105 if (imageDesc.sampleCountFlags > 1) {
106 desc = rngdCamLwrpMsaaGles_;
107 } else {
108 desc = rngdCamLwrpMsaa_;
109 }
110 }
111 } else if (renderCamera.renderPipelineType != RenderCamera::RenderPipelineType::LIGHT_FORWARD) {
112 desc = rngdCamHdr_;
113 } else {
114 desc = rngdCamLwrp_;
115 }
116 }
117 }
118 }
119 return desc;
120 }
121
GetRenderNodeGraphDesc(const RenderScene & renderScene,const RenderCamera & renderCamera,const uint32_t flags) const122 RenderNodeGraphDesc RenderUtil::GetRenderNodeGraphDesc(
123 const RenderScene& renderScene, const RenderCamera& renderCamera, const uint32_t flags) const
124 {
125 RenderNodeGraphDesc desc = SelectBaseDesc(renderCamera);
126 // process
127 desc.renderNodeGraphName = renderScene.name + to_hex(renderCamera.id);
128 for (auto& rnRef : desc.nodes) {
129 json::standalone_value jsonVal = CORE_NS::json::parse(rnRef.nodeJson.data());
130 jsonVal["customCameraId"] = renderCamera.id; // cam id
131 jsonVal["customCameraName"] = string(desc.renderNodeGraphName);
132 if (renderCamera.flags & RenderCamera::CAMERA_FLAG_REFLECTION_BIT) {
133 jsonVal["nodeFlags"] = 7u; // NOTE: hard coded
134 }
135 if (auto dataStore = jsonVal.find("renderDataStore"); dataStore) {
136 if (auto config = dataStore->find("configurationName"); config) {
137 if (!config->string_.empty()) {
138 auto renderDataStore = json::standalone_value { json::standalone_value::object {} };
139 renderDataStore["dataStoreName"] = "RenderDataStorePod";
140 renderDataStore["typeName"] = "PostProcess";
141 renderDataStore["configurationName"] = string(renderCamera.postProcessName);
142 jsonVal["renderDataStore"] = move(renderDataStore);
143 }
144 }
145 }
146 rnRef.nodeJson = to_string(jsonVal);
147 }
148
149 return desc;
150 }
151
GetRenderNodeGraphDesc(const RenderScene & renderScene,const uint32_t flags) const152 RenderNodeGraphDesc RenderUtil::GetRenderNodeGraphDesc(const RenderScene& renderScene, const uint32_t flags) const
153 {
154 RenderNodeGraphDesc desc;
155 if (!renderScene.customRenderNodeGraphFile.empty()) {
156 // custom render node graph file given which is patched
157 IRenderNodeGraphLoader& rngl = context_.GetRenderNodeGraphManager().GetRenderNodeGraphLoader();
158 desc = LoadRenderNodeGraph(rngl, renderScene.customRenderNodeGraphFile);
159 } else {
160 desc = rngdScene_;
161 }
162 const auto sceneIdStr = to_hex(renderScene.id);
163 const auto combinedStr = renderScene.name + sceneIdStr;
164 desc.renderNodeGraphName = combinedStr;
165 for (auto& rnRef : desc.nodes) {
166 json::standalone_value jsonVal = CORE_NS::json::parse(rnRef.nodeJson.data());
167 jsonVal[string_view("customId")] = renderScene.id; // cam id
168 jsonVal[string_view("customName")] = string(combinedStr);
169 rnRef.nodeJson = to_string(jsonVal);
170 }
171 return desc;
172 }
173 CORE3D_END_NAMESPACE()
174