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