1 /*
2  * Copyright (c) 2024 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_data_store_default_acceleration_structure_staging.h"
17 
18 #include <cstdint>
19 
20 #include <render/device/gpu_resource_desc.h>
21 #include <render/device/intf_device.h>
22 #include <render/device/intf_gpu_resource_manager.h>
23 #include <render/intf_render_context.h>
24 #include <render/namespace.h>
25 #include <render/resource_handle.h>
26 
27 #include "device/gpu_resource_manager.h"
28 #include "util/log.h"
29 
30 using namespace BASE_NS;
31 
RENDER_BEGIN_NAMESPACE()32 RENDER_BEGIN_NAMESPACE()
33 RenderDataStoreDefaultAccelerationStructureStaging::RenderDataStoreDefaultAccelerationStructureStaging(
34     IRenderContext& renderContext, const string_view name)
35     : gpuResourceMgr_(renderContext.GetDevice().GetGpuResourceManager()), name_(name)
36 {}
37 
~RenderDataStoreDefaultAccelerationStructureStaging()38 RenderDataStoreDefaultAccelerationStructureStaging::~RenderDataStoreDefaultAccelerationStructureStaging() {}
39 
PreRender()40 void RenderDataStoreDefaultAccelerationStructureStaging::PreRender()
41 {
42 #if (RENDER_VULKAN_RT_ENABLED == 1)
43     // get stuff ready for render nodes
44 
45     std::lock_guard<std::mutex> lock(mutex_);
46 
47     frameStagingBuild_ = move(stagingBuild_);
48     frameStagingInstance_ = move(stagingInstance_);
49 #endif
50 }
51 
PostRender()52 void RenderDataStoreDefaultAccelerationStructureStaging::PostRender() {}
53 
Clear()54 void RenderDataStoreDefaultAccelerationStructureStaging::Clear()
55 {
56     // The data cannot be automatically cleared here
57 }
58 
BuildAccelerationStructure(const StagingAccelerationStructureBuildGeometryData & buildData,const BASE_NS::array_view<const StagingAccelerationStructureGeometryTrianglesData> geometries)59 void RenderDataStoreDefaultAccelerationStructureStaging::BuildAccelerationStructure(
60     const StagingAccelerationStructureBuildGeometryData& buildData,
61     const BASE_NS::array_view<const StagingAccelerationStructureGeometryTrianglesData> geometries)
62 {
63 #if (RENDER_VULKAN_RT_ENABLED == 1)
64     std::lock_guard<std::mutex> lock(mutex_);
65 
66     if (!geometries.empty()) {
67         auto& geoms = stagingBuild_.triangles;
68         const uint32_t startIndex = static_cast<uint32_t>(geoms.size());
69         const uint32_t count = static_cast<uint32_t>(geometries.size());
70         geoms.reserve(startIndex + count);
71         for (const auto& geometriesRef : geometries) {
72             geoms.push_back(geometriesRef);
73         }
74         stagingBuild_.geometry.push_back(AccelerationStructureBuildConsumeStruct::Geom {
75             buildData,
76             GeometryType::CORE_GEOMETRY_TYPE_TRIANGLES,
77             startIndex,
78             count,
79         });
80     }
81 #endif
82 }
83 
BuildAccelerationStructure(const StagingAccelerationStructureBuildGeometryData & buildData,const BASE_NS::array_view<const StagingAccelerationStructureGeometryInstancesData> geometries)84 void RenderDataStoreDefaultAccelerationStructureStaging::BuildAccelerationStructure(
85     const StagingAccelerationStructureBuildGeometryData& buildData,
86     const BASE_NS::array_view<const StagingAccelerationStructureGeometryInstancesData> geometries)
87 {
88 #if (RENDER_VULKAN_RT_ENABLED == 1)
89     std::lock_guard<std::mutex> lock(mutex_);
90 
91     if (!geometries.empty()) {
92         auto& geoms = stagingBuild_.instances;
93         const uint32_t startIndex = static_cast<uint32_t>(geoms.size());
94         const uint32_t count = static_cast<uint32_t>(geometries.size());
95         geoms.reserve(startIndex + count);
96         for (const auto& geometriesRef : geometries) {
97             geoms.push_back(geometriesRef);
98         }
99         stagingBuild_.geometry.push_back(AccelerationStructureBuildConsumeStruct::Geom {
100             buildData,
101             GeometryType::CORE_GEOMETRY_TYPE_INSTANCES,
102             startIndex,
103             count,
104         });
105     }
106 #endif
107 }
108 
BuildAccelerationStructure(const StagingAccelerationStructureBuildGeometryData & buildData,const BASE_NS::array_view<const StagingAccelerationStructureGeometryAabbsData> geometries)109 void RenderDataStoreDefaultAccelerationStructureStaging::BuildAccelerationStructure(
110     const StagingAccelerationStructureBuildGeometryData& buildData,
111     const BASE_NS::array_view<const StagingAccelerationStructureGeometryAabbsData> geometries)
112 {
113 #if (RENDER_VULKAN_RT_ENABLED == 1)
114     std::lock_guard<std::mutex> lock(mutex_);
115 
116     if (!geometries.empty()) {
117         auto& geoms = stagingBuild_.aabbs;
118         const uint32_t startIndex = static_cast<uint32_t>(geoms.size());
119         const uint32_t count = static_cast<uint32_t>(geometries.size());
120         geoms.reserve(startIndex + count);
121         for (const auto& geometriesRef : geometries) {
122             geoms.push_back(geometriesRef);
123         }
124         stagingBuild_.geometry.push_back(AccelerationStructureBuildConsumeStruct::Geom {
125             buildData,
126             GeometryType::CORE_GEOMETRY_TYPE_AABBS,
127             startIndex,
128             count,
129         });
130     }
131 #endif
132 }
133 
CopyAccelerationStructureInstanceData(const RenderHandleReference & buffer,const uint32_t offset,const BASE_NS::array_view<const StagingAccelerationStructureInstance> instances)134 void RenderDataStoreDefaultAccelerationStructureStaging::CopyAccelerationStructureInstanceData(
135     const RenderHandleReference& buffer, const uint32_t offset,
136     const BASE_NS::array_view<const StagingAccelerationStructureInstance> instances)
137 {
138 #if (RENDER_VULKAN_RT_ENABLED == 1)
139     std::lock_guard<std::mutex> lock(mutex_);
140 
141     if ((!instances.empty()) && buffer) {
142         auto& ins = stagingInstance_.instances;
143         const uint32_t startIndex = static_cast<uint32_t>(ins.size());
144         const uint32_t count = static_cast<uint32_t>(instances.size());
145         ins.reserve(startIndex + count);
146         for (const auto& instancesRef : instances) {
147             ins.push_back(instancesRef);
148         }
149         stagingInstance_.copyInfo.push_back(AccelerationStructureInstanceConsumeStruct::Target {
150             { buffer, offset },
151             startIndex,
152             count,
153         });
154     }
155 #endif
156 }
157 
HasStagingData() const158 bool RenderDataStoreDefaultAccelerationStructureStaging::HasStagingData() const
159 {
160     if (frameStagingBuild_.geometry.empty() && frameStagingInstance_.copyInfo.empty()) {
161         return false;
162     } else {
163         return true;
164     }
165 }
166 
ConsumeStagingBuildData()167 AccelerationStructureBuildConsumeStruct RenderDataStoreDefaultAccelerationStructureStaging::ConsumeStagingBuildData()
168 {
169     AccelerationStructureBuildConsumeStruct scs = move(frameStagingBuild_);
170     return scs;
171 }
172 
173 AccelerationStructureInstanceConsumeStruct
ConsumeStagingInstanceData()174 RenderDataStoreDefaultAccelerationStructureStaging::ConsumeStagingInstanceData()
175 {
176     AccelerationStructureInstanceConsumeStruct scs = move(frameStagingInstance_);
177     return scs;
178 }
179 
180 // for plugin / factory interface
Create(IRenderContext & renderContext,char const * name)181 IRenderDataStore* RenderDataStoreDefaultAccelerationStructureStaging::Create(
182     IRenderContext& renderContext, char const* name)
183 {
184     return new RenderDataStoreDefaultAccelerationStructureStaging(renderContext, name);
185 }
186 
Destroy(IRenderDataStore * instance)187 void RenderDataStoreDefaultAccelerationStructureStaging::Destroy(IRenderDataStore* instance)
188 {
189     delete static_cast<RenderDataStoreDefaultAccelerationStructureStaging*>(instance);
190 }
191 RENDER_END_NAMESPACE()
192