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 #ifndef DEVICE_SHADER_PIPELINE_BINDER_H
17 #define DEVICE_SHADER_PIPELINE_BINDER_H
18 
19 #include <atomic>
20 
21 #include <base/containers/array_view.h>
22 #include <base/containers/refcnt_ptr.h>
23 #include <render/device/intf_shader_pipeline_binder.h>
24 #include <render/namespace.h>
25 #include <render/resource_handle.h>
26 
27 #include "util/property_util.h"
28 
29 RENDER_BEGIN_NAMESPACE()
30 class ShaderPipelineBinder;
31 
32 class ShaderPipelineBinderPropertyBindingSignal final : public CustomPropertyWriteSignal {
33 public:
34     explicit ShaderPipelineBinderPropertyBindingSignal(ShaderPipelineBinder& shaderPipelineBinder);
35     ~ShaderPipelineBinderPropertyBindingSignal() override = default;
36 
37     void Signal() override;
38 
39 private:
40     ShaderPipelineBinder& shaderPipelineBinder_;
41 };
42 
43 class ShaderPipelineBinder : public IShaderPipelineBinder {
44 public:
45     ShaderPipelineBinder() = delete;
46     ShaderPipelineBinder(
47         IShaderManager& shaderMgr, const RenderHandleReference& shader, const PipelineLayout& pipelineLayout);
48     ~ShaderPipelineBinder() override = default;
49 
50     void ClearBindings() override;
51     bool GetBindingValidity() const override;
52     RenderHandleReference GetShaderHandle() const override;
53 
54     void Bind(const uint32_t set, const uint32_t binding, const RenderHandleReference& handle) override;
55     // Not yet in the API
56     void SetUniformData(const uint32_t set, const uint32_t binding, const BASE_NS::array_view<const uint8_t> data);
57     void SetPushConstantData(const BASE_NS::array_view<const uint8_t> data) override;
58 
59     void BindBuffer(
60         const uint32_t set, const uint32_t binding, const BindableBufferWithHandleReference& resource) override;
61     void BindBuffers(const uint32_t set, const uint32_t binding,
62         BASE_NS::array_view<const BindableBufferWithHandleReference> resources) override;
63     void BindImage(
64         const uint32_t set, const uint32_t binding, const BindableImageWithHandleReference& resource) override;
65     void BindImages(const uint32_t set, const uint32_t binding,
66         BASE_NS::array_view<const BindableImageWithHandleReference> resources) override;
67     void BindSampler(
68         const uint32_t set, const uint32_t binding, const BindableSamplerWithHandleReference& resource) override;
69     void BindSamplers(const uint32_t set, const uint32_t binding,
70         BASE_NS::array_view<const BindableSamplerWithHandleReference> resources) override;
71 
72     void BindVertexBuffers(BASE_NS::array_view<const VertexBufferWithHandleReference> vertexBuffers) override;
73     void BindIndexBuffer(const IndexBufferWithHandleReference& indexBuffer) override;
74     void SetDrawCommand(const DrawCommand& drawCommand) override;
75     void SetDispatchCommand(const DispatchCommand& dispatchCommand) override;
76 
77     DescriptorSetLayoutBindingResources GetDescriptorSetLayoutBindingResources(const uint32_t set) const override;
78 
79     BASE_NS::array_view<const uint8_t> GetPushConstantData() const override;
80 
81     BASE_NS::array_view<const VertexBufferWithHandleReference> GetVertexBuffers() const override;
82     IndexBufferWithHandleReference GetIndexBuffer() const override;
83     DrawCommand GetDrawCommand() const override;
84     DispatchCommand GetDispatchCommand() const override;
85 
86     PipelineLayout GetPipelineLayout() const override;
87     IPipelineDescriptorSetBinder* GetPipelineDescriptorSetBinder() const;
88 
89     CORE_NS::IPropertyHandle* GetProperties() override;
90     CORE_NS::IPropertyHandle* GetBindingProperties() override;
91     ResourceBinding GetResourceBinding(uint32_t set, uint32_t binding) const override;
92     PropertyBindingView GetPropertyBindingView() const override;
93     uint32_t GetPropertyBindingByteSize() const override;
94 
95     void BindPropertyBindings();
96 
97     struct CustomPropertyData {
98         uint32_t set { ~0U };
99         uint32_t binding { ~0U };
100 
101         BASE_NS::unique_ptr<CustomPropertyPodContainer> properties;
102         CORE_NS::IPropertyHandle* handle { nullptr };
103     };
104     struct BindingPropertyData {
105         struct SetAndBinding {
106             uint32_t set { ~0U };
107             uint32_t binding { ~0U };
108         };
109 
110         BASE_NS::unique_ptr<ShaderPipelineBinderPropertyBindingSignal> bindingSignal;
111 
112         BASE_NS::unique_ptr<CustomPropertyBindingContainer> properties;
113         CORE_NS::IPropertyHandle* handle { nullptr };
114         BASE_NS::vector<SetAndBinding> setAndBindings;
115     };
116 
117     struct BindableBinding {
118         uint32_t binding { ~0U };
119         uint32_t descriptorCount { ~0U };
120         uint32_t resIdx { ~0U };
121         uint32_t arrayoffset { ~0U };
122         RenderHandleType type { RenderHandleType::UNDEFINED };
123     };
124 
125 protected:
126     void Ref() override;
127     void Unref() override;
128 
129 private:
130     void InitCustomProperties();
131     void EvaluateCustomPropertyBindings();
132 
133     IShaderManager& shaderMgr_;
134 
135     std::atomic<int32_t> refcnt_ { 0 };
136 
137     RenderHandleReference shader_;
138     PipelineLayout pipelineLayout_;
139 
140     RenderHandleType renderHandleType_ { RenderHandleType::UNDEFINED };
141 
142     DispatchCommand dispatchCommand_;
143     DrawCommand drawCommand_;
144 
145     BASE_NS::vector<VertexBufferWithHandleReference> vertexBuffers_;
146     IndexBufferWithHandleReference indexBuffer_;
147 
148     // NOTE: initial version with multiple vectors per descriptor set
149     // vectors are resized in the constructor
150     struct DescriptorSetResources {
151         BASE_NS::vector<BindableBufferWithHandleReference> buffers;
152         BASE_NS::vector<BindableImageWithHandleReference> images;
153         BASE_NS::vector<BindableSamplerWithHandleReference> samplers;
154 
155         BASE_NS::vector<BindableBinding> bindings;
156 
157         uint8_t bindingToIndex[PipelineLayoutConstants::MAX_DESCRIPTOR_SET_BINDING_COUNT] { 16, 16, 16, 16, 16, 16, 16,
158             16, 16, 16, 16, 16, 16, 16, 16, 16 };
159     };
160     BASE_NS::vector<DescriptorSetResources> descriptorSetResources_;
161 
162     BASE_NS::vector<uint8_t> pushData_;
163 
164     CustomPropertyData customPropertyData_;
165     BindingPropertyData bindingPropertyData_;
166 
167     // real binder object which can be re-used immediately during rendering
168     IPipelineDescriptorSetBinder::Ptr pipelineDescriptorSetBinder_;
169     // set -> actual vector index
170     uint32_t setToBinderIndex_[PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT] { ~0u, ~0u, ~0u, ~0u };
171 };
172 RENDER_END_NAMESPACE()
173 
174 #endif // DEVICE_SHADER_PIPELINE_BINDER_H
175