1 /*
2 * Copyright (c) 2022 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_shader_passes.h"
17
18 #include <cstdint>
19
20 #include <base/containers/fixed_string.h>
21 #include <render/device/intf_shader_manager.h>
22 #include <render/intf_render_context.h>
23
24 #include "util/log.h"
25
26 using namespace BASE_NS;
27
28 RENDER_BEGIN_NAMESPACE()
29 namespace {
30 constexpr uint32_t OFFSET_ALIGNMENT { PipelineLayoutConstants::MIN_UBO_BIND_OFFSET_ALIGNMENT_BYTE_SIZE };
31
Align(uint32_t value,uint32_t align)32 constexpr uint32_t Align(uint32_t value, uint32_t align)
33 {
34 if (value == 0) {
35 return 0;
36 }
37 return ((value + align) / align) * align;
38 }
39 } // namespace
40
RenderDataStoreShaderPasses(const IRenderContext &,const string_view name)41 RenderDataStoreShaderPasses::RenderDataStoreShaderPasses(
42 const IRenderContext& /* renderContext */, const string_view name)
43 : name_(name)
44 {}
45
PostRender()46 void RenderDataStoreShaderPasses::PostRender()
47 {
48 Clear();
49 }
50
Clear()51 void RenderDataStoreShaderPasses::Clear()
52 {
53 const auto lock = std::lock_guard(mutex_);
54
55 nameToRenderObjects_.clear();
56 nameToComputeObjects_.clear();
57 }
58
Ref()59 void RenderDataStoreShaderPasses::Ref()
60 {
61 refcnt_.fetch_add(1, std::memory_order_relaxed);
62 }
63
Unref()64 void RenderDataStoreShaderPasses::Unref()
65 {
66 if (std::atomic_fetch_sub_explicit(&refcnt_, 1, std::memory_order_release) == 1) {
67 std::atomic_thread_fence(std::memory_order_acquire);
68 delete this;
69 }
70 }
71
GetRefCount()72 int32_t RenderDataStoreShaderPasses::GetRefCount()
73 {
74 return refcnt_;
75 }
76
AddRenderData(const BASE_NS::string_view name,const BASE_NS::array_view<const RenderPassData> data)77 void RenderDataStoreShaderPasses::AddRenderData(
78 const BASE_NS::string_view name, const BASE_NS::array_view<const RenderPassData> data)
79 {
80 if ((!name.empty()) && (!data.empty())) {
81 const auto lock = std::lock_guard(mutex_);
82
83 auto& ref = nameToRenderObjects_[name];
84 ref.rpData.append(data.begin(), data.end());
85 for (const auto& rpRef : ref.rpData) {
86 for (const auto& shaderRef : rpRef.shaderBinders) {
87 if (shaderRef) {
88 ref.alignedPropertyByteSize += Align(shaderRef->GetPropertyBindingByteSize(), OFFSET_ALIGNMENT);
89 }
90 }
91 }
92 }
93 }
94
AddComputeData(const BASE_NS::string_view name,const BASE_NS::array_view<const ComputePassData> data)95 void RenderDataStoreShaderPasses::AddComputeData(
96 const BASE_NS::string_view name, const BASE_NS::array_view<const ComputePassData> data)
97 {
98 if ((!name.empty()) && (!data.empty())) {
99 const auto lock = std::lock_guard(mutex_);
100
101 auto& ref = nameToComputeObjects_[name];
102 ref.cpData.append(data.begin(), data.end());
103 for (const auto& rpRef : ref.cpData) {
104 for (const auto& shaderRef : rpRef.shaderBinders) {
105 if (shaderRef) {
106 ref.alignedPropertyByteSize += Align(shaderRef->GetPropertyBindingByteSize(), OFFSET_ALIGNMENT);
107 }
108 }
109 }
110 }
111 }
112
GetRenderData(const BASE_NS::string_view name) const113 vector<IRenderDataStoreShaderPasses::RenderPassData> RenderDataStoreShaderPasses::GetRenderData(
114 const BASE_NS::string_view name) const
115 {
116 const auto lock = std::lock_guard(mutex_);
117
118 if (const auto iter = nameToRenderObjects_.find(name); iter != nameToRenderObjects_.cend()) {
119 return iter->second.rpData;
120 }
121 return {};
122 }
123
GetComputeData(const BASE_NS::string_view name) const124 vector<IRenderDataStoreShaderPasses::ComputePassData> RenderDataStoreShaderPasses::GetComputeData(
125 const BASE_NS::string_view name) const
126 {
127 const auto lock = std::lock_guard(mutex_);
128
129 if (const auto iter = nameToComputeObjects_.find(name); iter != nameToComputeObjects_.cend()) {
130 return iter->second.cpData;
131 }
132 return {};
133 }
134
GetRenderData() const135 vector<IRenderDataStoreShaderPasses::RenderPassData> RenderDataStoreShaderPasses::GetRenderData() const
136 {
137 const auto lock = std::lock_guard(mutex_);
138
139 BASE_NS::vector<RenderPassData> data;
140 data.reserve(nameToRenderObjects_.size());
141 for (const auto& ref : nameToRenderObjects_) {
142 data.append(ref.second.rpData.begin(), ref.second.rpData.end());
143 }
144 return data;
145 }
146
GetComputeData() const147 vector<IRenderDataStoreShaderPasses::ComputePassData> RenderDataStoreShaderPasses::GetComputeData() const
148 {
149 const auto lock = std::lock_guard(mutex_);
150
151 BASE_NS::vector<ComputePassData> data;
152 data.reserve(nameToComputeObjects_.size());
153 for (const auto& ref : nameToComputeObjects_) {
154 data.append(ref.second.cpData.begin(), ref.second.cpData.end());
155 }
156 return data;
157 }
158
GetRenderPropertyBindingInfo(BASE_NS::string_view name) const159 RenderDataStoreShaderPasses::PropertyBindingDataInfo RenderDataStoreShaderPasses::GetRenderPropertyBindingInfo(
160 BASE_NS::string_view name) const
161 {
162 const auto lock = std::lock_guard(mutex_);
163
164 if (const auto iter = nameToRenderObjects_.find(name); iter != nameToRenderObjects_.cend()) {
165 return { iter->second.alignedPropertyByteSize };
166 }
167 return {};
168 }
169
GetComputePropertyBindingInfo(BASE_NS::string_view name) const170 RenderDataStoreShaderPasses::PropertyBindingDataInfo RenderDataStoreShaderPasses::GetComputePropertyBindingInfo(
171 BASE_NS::string_view name) const
172 {
173 const auto lock = std::lock_guard(mutex_);
174
175 if (const auto iter = nameToComputeObjects_.find(name); iter != nameToComputeObjects_.cend()) {
176 return { iter->second.alignedPropertyByteSize };
177 }
178 return {};
179 }
180
GetRenderPropertyBindingInfo() const181 RenderDataStoreShaderPasses::PropertyBindingDataInfo RenderDataStoreShaderPasses::GetRenderPropertyBindingInfo() const
182 {
183 const auto lock = std::lock_guard(mutex_);
184
185 PropertyBindingDataInfo info;
186 for (const auto& ref : nameToRenderObjects_) {
187 info.alignedByteSize = ref.second.alignedPropertyByteSize;
188 }
189 return info;
190 }
191
GetComputePropertyBindingInfo() const192 RenderDataStoreShaderPasses::PropertyBindingDataInfo RenderDataStoreShaderPasses::GetComputePropertyBindingInfo() const
193 {
194 const auto lock = std::lock_guard(mutex_);
195
196 PropertyBindingDataInfo info;
197 for (const auto& ref : nameToComputeObjects_) {
198 info.alignedByteSize = ref.second.alignedPropertyByteSize;
199 }
200 return info;
201 }
202
203 // for plugin / factory interface
Create(IRenderContext & renderContext,const char * name)204 refcnt_ptr<IRenderDataStore> RenderDataStoreShaderPasses::Create(IRenderContext& renderContext, const char* name)
205 {
206 return refcnt_ptr<IRenderDataStore>(new RenderDataStoreShaderPasses(renderContext, name));
207 }
208 RENDER_END_NAMESPACE()
209