• 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#ifndef DEVICE_GPU_RESOURCE_MANAGER_BASE_INL
17#define DEVICE_GPU_RESOURCE_MANAGER_BASE_INL
18
19#include <algorithm>
20#include <cinttypes>
21
22#include <render/namespace.h>
23
24#include "util/log.h"
25
26RENDER_BEGIN_NAMESPACE()
27template<typename ResourceType, typename CreateInfoType>
28inline GpuResourceManagerTyped<ResourceType, CreateInfoType>::GpuResourceManagerTyped(Device& device) : device_(device)
29{}
30
31template<typename ResourceType, typename CreateInfoType>
32inline ResourceType* GpuResourceManagerTyped<ResourceType, CreateInfoType>::Get(const uint32_t index) const
33{
34    if (index < resources_.size()) {
35        return resources_[index].get();
36    } else {
37        return nullptr;
38    }
39}
40
41template<typename ResourceType, typename CreateInfoType>
42inline void GpuResourceManagerTyped<ResourceType, CreateInfoType>::Create(
43    const uint32_t index, const CreateInfoType& desc, BASE_NS::unique_ptr<ResourceType> optionalResource)
44{
45    if (index < static_cast<uint32_t>(resources_.size())) { // use existing location
46        // add old for deallocation if found
47        if (resources_[index]) {
48            pendingDeallocations_.push_back({ move(resources_[index]), device_.GetFrameCount() });
49        }
50
51        if (optionalResource) {
52            resources_[index] = move(optionalResource);
53        } else {
54            if constexpr (BASE_NS::is_same_v<ResourceType, GpuBuffer>) {
55                resources_[index] = device_.CreateGpuBuffer(desc);
56            } else if constexpr (BASE_NS::is_same_v<ResourceType, GpuImage>) {
57                resources_[index] = device_.CreateGpuImage(desc);
58            } else if constexpr (BASE_NS::is_same_v<ResourceType, GpuSampler>) {
59                resources_[index] = device_.CreateGpuSampler(desc);
60            } else if constexpr (BASE_NS::is_same_v<ResourceType, GpuAccelerationStructure>) {
61                resources_[index] = device_.CreateGpuAccelerationStructure(desc);
62            }
63        }
64    } else {
65        if (optionalResource) {
66            resources_.emplace_back(move(optionalResource));
67        } else {
68            if constexpr (BASE_NS::is_same_v<ResourceType, GpuBuffer>) {
69                resources_.emplace_back(device_.CreateGpuBuffer(desc));
70            } else if constexpr (BASE_NS::is_same_v<ResourceType, GpuImage>) {
71                resources_.emplace_back(device_.CreateGpuImage(desc));
72            } else if constexpr (BASE_NS::is_same_v<ResourceType, GpuSampler>) {
73                resources_.emplace_back(device_.CreateGpuSampler(desc));
74            } else if constexpr (BASE_NS::is_same_v<ResourceType, GpuAccelerationStructure>) {
75                resources_.emplace_back(device_.CreateGpuAccelerationStructure(desc));
76            }
77        }
78        PLUGIN_ASSERT(index == static_cast<uint32_t>(resources_.size() - 1u));
79    }
80}
81
82template<typename ResourceType, typename CreateInfoType>
83inline void GpuResourceManagerTyped<ResourceType, CreateInfoType>::HandlePendingDeallocations()
84{
85    if (!pendingDeallocations_.empty()) {
86        auto const minAge = device_.GetCommandBufferingCount() + 1;
87        auto const ageLimit = (device_.GetFrameCount() < minAge) ? 0 : (device_.GetFrameCount() - minAge);
88
89        auto const oldResources = std::partition(pendingDeallocations_.begin(), pendingDeallocations_.end(),
90            [ageLimit](auto const& handleTime) { return handleTime.frameIndex >= ageLimit; });
91
92        pendingDeallocations_.erase(oldResources, pendingDeallocations_.end());
93    }
94}
95
96template<typename ResourceType, typename CreateInfoType>
97inline void GpuResourceManagerTyped<ResourceType, CreateInfoType>::HandlePendingDeallocationsImmediate()
98{
99    pendingDeallocations_.clear();
100}
101
102template<typename ResourceType, typename CreateInfoType>
103inline void GpuResourceManagerTyped<ResourceType, CreateInfoType>::Destroy(const uint32_t index)
104{
105    PLUGIN_ASSERT(index < static_cast<uint32_t>(resources_.size()));
106    if (index < static_cast<uint32_t>(resources_.size())) {
107        pendingDeallocations_.push_back({ move(resources_[index]), device_.GetFrameCount() });
108    }
109}
110
111template<typename ResourceType, typename CreateInfoType>
112inline void GpuResourceManagerTyped<ResourceType, CreateInfoType>::DestroyImmediate(const uint32_t index)
113{
114    PLUGIN_ASSERT(index < static_cast<uint32_t>(resources_.size()));
115    if (index < static_cast<uint32_t>(resources_.size())) {
116        resources_[index].reset();
117    }
118}
119
120template<typename ResourceType, typename CreateInfoType>
121inline void GpuResourceManagerTyped<ResourceType, CreateInfoType>::Resize(const size_t maxSize)
122{
123    // ATM our code does not allow reducing the stored space
124    // this assert is here to note the current design
125    PLUGIN_ASSERT(maxSize >= resources_.size());
126    resources_.resize(maxSize);
127}
128
129#if (RENDER_VALIDATION_ENABLED == 1)
130template<typename ResourceType, typename CreateInfoType>
131size_t GpuResourceManagerTyped<ResourceType, CreateInfoType>::GetValidResourceCount() const
132{
133    size_t count = 0;
134    for (const auto& res : resources_) {
135        if (res) {
136            count++;
137        }
138    }
139    return count;
140}
141#endif
142RENDER_END_NAMESPACE()
143
144#endif // DEVICE_GPU_RESOURCE_MANAGER_BASE_INL