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 <cinttypes>
19 #include <cstdint>
20 
21 #include <base/containers/fixed_string.h>
22 #include <render/device/intf_shader_manager.h>
23 #include <render/intf_render_context.h>
24 
25 #include "util/log.h"
26 
27 using namespace BASE_NS;
28 
29 RENDER_BEGIN_NAMESPACE()
30 namespace {
31 constexpr uint32_t OFFSET_ALIGNMENT { PipelineLayoutConstants::MIN_UBO_BIND_OFFSET_ALIGNMENT_BYTE_SIZE };
32 
Align(uint32_t value,uint32_t align)33 constexpr uint32_t Align(uint32_t value, uint32_t align)
34 {
35     if (value == 0) {
36         return 0;
37     }
38     return ((value + align) / align) * align;
39 }
40 }// namespace
41 
RenderDataStoreShaderPasses(const IRenderContext & renderContext,const string_view name)42 RenderDataStoreShaderPasses::RenderDataStoreShaderPasses(const IRenderContext& renderContext, const string_view name)
43     : renderContext_(renderContext), name_(name)
44 {}
45 
~RenderDataStoreShaderPasses()46 RenderDataStoreShaderPasses::~RenderDataStoreShaderPasses() {}
47 
PostRender()48 void RenderDataStoreShaderPasses::PostRender()
49 {
50     Clear();
51 }
52 
Clear()53 void RenderDataStoreShaderPasses::Clear()
54 {
55     const auto lock = std::lock_guard(mutex_);
56 
57     nameToRenderObjects_.clear();
58     nameToComputeObjects_.clear();
59 }
60 
AddRenderData(const BASE_NS::string_view name,const BASE_NS::array_view<const RenderPassData> data)61 void RenderDataStoreShaderPasses::AddRenderData(
62     const BASE_NS::string_view name, const BASE_NS::array_view<const RenderPassData> data)
63 {
64     if ((!name.empty()) && (!data.empty())) {
65         const auto lock = std::lock_guard(mutex_);
66 
67         auto& ref = nameToRenderObjects_[name];
68         ref.rpData.append(data.begin(), data.end());
69         for (const auto& rpRef : ref.rpData) {
70             for (const auto& shaderRef : rpRef.shaderBinders) {
71                 if (shaderRef) {
72                     ref.alignedPropertyByteSize = Align(shaderRef->GetPropertyBindingByteSize(), OFFSET_ALIGNMENT);
73                 }
74             }
75         }
76     }
77 }
78 
AddComputeData(const BASE_NS::string_view name,const BASE_NS::array_view<const ComputePassData> data)79 void RenderDataStoreShaderPasses::AddComputeData(
80     const BASE_NS::string_view name, const BASE_NS::array_view<const ComputePassData> data)
81 {
82     if ((!name.empty()) && (!data.empty())) {
83         const auto lock = std::lock_guard(mutex_);
84 
85         auto& ref = nameToComputeObjects_[name];
86         ref.cpData.append(data.begin(), data.end());
87         for (const auto& rpRef : ref.cpData) {
88             for (const auto& shaderRef : rpRef.shaderBinders) {
89                 if (shaderRef) {
90                     ref.alignedPropertyByteSize = Align(shaderRef->GetPropertyBindingByteSize(), OFFSET_ALIGNMENT);
91                 }
92             }
93         }
94     }
95 }
96 
GetRenderData(const BASE_NS::string_view name) const97 vector<IRenderDataStoreShaderPasses::RenderPassData> RenderDataStoreShaderPasses::GetRenderData(
98     const BASE_NS::string_view name) const
99 {
100     const auto lock = std::lock_guard(mutex_);
101 
102     if (const auto iter = nameToRenderObjects_.find(name); iter != nameToRenderObjects_.cend()) {
103         return iter->second.rpData;
104     }
105     return {};
106 }
107 
GetComputeData(const BASE_NS::string_view name) const108 vector<IRenderDataStoreShaderPasses::ComputePassData> RenderDataStoreShaderPasses::GetComputeData(
109     const BASE_NS::string_view name) const
110 {
111     const auto lock = std::lock_guard(mutex_);
112 
113     if (const auto iter = nameToComputeObjects_.find(name); iter != nameToComputeObjects_.cend()) {
114         return iter->second.cpData;
115     }
116     return {};
117 }
118 
GetRenderData() const119 vector<IRenderDataStoreShaderPasses::RenderPassData> RenderDataStoreShaderPasses::GetRenderData() const
120 {
121     const auto lock = std::lock_guard(mutex_);
122 
123     BASE_NS::vector<RenderPassData> data;
124     data.reserve(nameToRenderObjects_.size());
125     for (const auto& ref : nameToRenderObjects_) {
126         data.append(ref.second.rpData.begin(), ref.second.rpData.end());
127     }
128     return data;
129 }
130 
GetComputeData() const131 vector<IRenderDataStoreShaderPasses::ComputePassData> RenderDataStoreShaderPasses::GetComputeData() const
132 {
133     const auto lock = std::lock_guard(mutex_);
134 
135     BASE_NS::vector<ComputePassData> data;
136     data.reserve(nameToComputeObjects_.size());
137     for (const auto& ref : nameToComputeObjects_) {
138         data.append(ref.second.cpData.begin(), ref.second.cpData.end());
139     }
140     return data;
141 }
142 
GetRenderPropertyBindingInfo(BASE_NS::string_view name) const143 RenderDataStoreShaderPasses::PropertyBindingDataInfo RenderDataStoreShaderPasses::GetRenderPropertyBindingInfo(
144     BASE_NS::string_view name) const
145 {
146     const auto lock = std::lock_guard(mutex_);
147 
148     if (const auto iter = nameToRenderObjects_.find(name); iter != nameToRenderObjects_.cend()) {
149         return { iter->second.alignedPropertyByteSize };
150     }
151     return {};
152 }
153 
GetComputePropertyBindingInfo(BASE_NS::string_view name) const154 RenderDataStoreShaderPasses::PropertyBindingDataInfo RenderDataStoreShaderPasses::GetComputePropertyBindingInfo(
155     BASE_NS::string_view name) const
156 {
157     const auto lock = std::lock_guard(mutex_);
158 
159     if (const auto iter = nameToComputeObjects_.find(name); iter != nameToComputeObjects_.cend()) {
160         return { iter->second.alignedPropertyByteSize };
161     }
162     return {};
163 }
164 
GetRenderPropertyBindingInfo() const165 RenderDataStoreShaderPasses::PropertyBindingDataInfo RenderDataStoreShaderPasses::GetRenderPropertyBindingInfo() const
166 {
167     const auto lock = std::lock_guard(mutex_);
168 
169     PropertyBindingDataInfo info;
170     for (const auto& ref : nameToRenderObjects_) {
171         info.alignedByteSize = ref.second.alignedPropertyByteSize;
172     }
173     return info;
174 }
175 
GetComputePropertyBindingInfo() const176 RenderDataStoreShaderPasses::PropertyBindingDataInfo RenderDataStoreShaderPasses::GetComputePropertyBindingInfo() const
177 {
178     const auto lock = std::lock_guard(mutex_);
179 
180     PropertyBindingDataInfo info;
181     for (const auto& ref : nameToComputeObjects_) {
182         info.alignedByteSize = ref.second.alignedPropertyByteSize;
183     }
184     return info;
185 }
186 
187 // for plugin / factory interface
Create(IRenderContext & renderContext,char const * name)188 IRenderDataStore* RenderDataStoreShaderPasses::Create(IRenderContext& renderContext, char const* name)
189 {
190     // engine not used
191     return new RenderDataStoreShaderPasses(renderContext, name);
192 }
193 
Destroy(IRenderDataStore * instance)194 void RenderDataStoreShaderPasses::Destroy(IRenderDataStore* instance)
195 {
196     delete static_cast<RenderDataStoreShaderPasses*>(instance);
197 }
198 RENDER_END_NAMESPACE()
199