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 RENDER_RENDER__PIPELINE_DESCRIPTOR_SET_BINDER_H
17 #define RENDER_RENDER__PIPELINE_DESCRIPTOR_SET_BINDER_H
18
19 #include <cstdint>
20
21 #include <base/containers/array_view.h>
22 #include <base/containers/vector.h>
23 #include <render/device/pipeline_layout_desc.h>
24 #include <render/device/pipeline_state_desc.h>
25 #include <render/namespace.h>
26 #include <render/nodecontext/intf_pipeline_descriptor_set_binder.h>
27 #include <render/resource_handle.h>
28
29 #include "device/gpu_resource_handle_util.h"
30 #include "util/log.h"
31
RENDER_BEGIN_NAMESPACE()32 RENDER_BEGIN_NAMESPACE()
33 namespace DescriptorSetBinderUtil {
34 constexpr RenderHandleType GetRenderHandleType(const DescriptorType dt)
35 {
36 if (dt == CORE_DESCRIPTOR_TYPE_SAMPLER) {
37 return RenderHandleType::GPU_SAMPLER;
38 } else if (((dt >= CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) && (dt <= CORE_DESCRIPTOR_TYPE_STORAGE_IMAGE)) ||
39 (dt == CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
40 return RenderHandleType::GPU_IMAGE;
41 } else if (((dt >= CORE_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) &&
42 (dt <= CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) ||
43 (dt == CORE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE)) {
44 return RenderHandleType::GPU_BUFFER;
45 }
46 return RenderHandleType::UNDEFINED;
47 }
48
49 constexpr PipelineStageFlags GetPipelineStageFlags(const ShaderStageFlags shaderStageFlags)
50 {
51 PipelineStageFlags pipelineStageFlags { 0 };
52 if (shaderStageFlags & ShaderStageFlagBits::CORE_SHADER_STAGE_VERTEX_BIT) {
53 pipelineStageFlags |= PipelineStageFlagBits::CORE_PIPELINE_STAGE_VERTEX_SHADER_BIT;
54 }
55 if (shaderStageFlags & ShaderStageFlagBits::CORE_SHADER_STAGE_FRAGMENT_BIT) {
56 pipelineStageFlags |= PipelineStageFlagBits::CORE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
57 }
58 if (shaderStageFlags & ShaderStageFlagBits::CORE_SHADER_STAGE_COMPUTE_BIT) {
59 pipelineStageFlags |= PipelineStageFlagBits::CORE_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
60 }
61 return pipelineStageFlags;
62 }
63
64 constexpr AccessFlags GetAccessFlags(const DescriptorType dt)
65 {
66 if ((dt == CORE_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) || (dt == CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
67 (dt == CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)) {
68 return CORE_ACCESS_UNIFORM_READ_BIT;
69 } else if ((dt == CORE_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) || (dt == CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
70 (dt == CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) || (dt == CORE_DESCRIPTOR_TYPE_STORAGE_IMAGE)) {
71 // NOTE: could be optimized with shader reflection info
72 return (CORE_ACCESS_SHADER_READ_BIT | CORE_ACCESS_SHADER_WRITE_BIT);
73 } else if (dt == CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) {
74 return CORE_ACCESS_INPUT_ATTACHMENT_READ_BIT;
75 } else {
76 // CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
77 // CORE_DESCRIPTOR_TYPE_SAMPLED_IMAGE
78 // CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
79 // CORE_DESCRIPTOR_TYPE_SAMPLER
80 // CORE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE
81 return CORE_ACCESS_SHADER_READ_BIT;
82 }
83 }
84 } // namespace DescriptorSetBinderUtil
85
86 /** DescriptorSetBinder.
87 */
88 class DescriptorSetBinder final : public IDescriptorSetBinder {
89 public:
90 DescriptorSetBinder(const RenderHandle handle,
91 const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings);
92 explicit DescriptorSetBinder(
93 const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings);
94 ~DescriptorSetBinder() = default;
95
96 void ClearBindings() override;
97 RenderHandle GetDescriptorSetHandle() const override;
98 DescriptorSetLayoutBindingResources GetDescriptorSetLayoutBindingResources() const override;
99
100 bool GetDescriptorSetLayoutBindingValidity() const override;
101 void PrintDescriptorSetLayoutBindingValidation() const override;
102
103 // all must call this
104 void BindBuffer(
105 const uint32_t binding, const BindableBuffer& resource, const AdditionalDescriptorFlags flags) override;
106 void BindBuffer(const uint32_t binding, const BindableBuffer& resource) override;
107 void BindBuffer(const uint32_t binding, const RenderHandle handle, const uint32_t byteOffset) override;
108 void BindBuffer(
109 const uint32_t binding, const RenderHandle handle, const uint32_t byteOffset, const uint32_t byteSize) override;
110 // for descriptor array binding
111 void BindBuffers(const uint32_t binding, const BASE_NS::array_view<const BindableBuffer> resources) override;
112
113 // all must call this
114 void BindImage(
115 const uint32_t binding, const BindableImage& resource, const AdditionalDescriptorFlags flags) override;
116 void BindImage(const uint32_t binding, const BindableImage& resource) override;
117 void BindImage(const uint32_t binding, const RenderHandle handle) override;
118 void BindImage(const uint32_t binding, const RenderHandle handle, const RenderHandle samplerHandle) override;
119 // for descriptor array binding
120 void BindImages(const uint32_t binding, const BASE_NS::array_view<const BindableImage> resources) override;
121
122 // all must call this
123 void BindSampler(
124 const uint32_t binding, const BindableSampler& resource, const AdditionalDescriptorFlags flags) override;
125 void BindSampler(const uint32_t binding, const BindableSampler& resource) override;
126 void BindSampler(const uint32_t binding, const RenderHandle handle) override;
127 // for descriptor array binding
128 void BindSamplers(const uint32_t binding, const BASE_NS::array_view<const BindableSampler> resources) override;
129
130 protected:
131 void Destroy() override;
132
133 private:
134 void Init(const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings);
135 void InitFillBindings(const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings,
136 const uint32_t bufferCount, const uint32_t imageCount, const uint32_t samplerCount);
137
138 RenderHandle handle_;
139 BASE_NS::vector<DescriptorSetLayoutBindingResource> bindings_;
140
141 BASE_NS::vector<BufferDescriptor> buffers_;
142 BASE_NS::vector<ImageDescriptor> images_;
143 BASE_NS::vector<SamplerDescriptor> samplers_;
144
145 // accesses array with binding number and retuns index;
146 PLUGIN_STATIC_ASSERT(PipelineLayoutConstants::MAX_DESCRIPTOR_SET_BINDING_COUNT == 16u);
147 uint8_t bindingToIndex_[PipelineLayoutConstants::MAX_DESCRIPTOR_SET_BINDING_COUNT] { 16, 16, 16, 16, 16, 16, 16, 16,
148 16, 16, 16, 16, 16, 16, 16, 16 };
149 uint32_t maxBindingCount_ { 0u };
150
151 uint32_t descriptorBindingMask_ { 0 };
152 uint32_t bindingMask_ { 0 };
153 };
154
155 /** PipelineDescriptorSetBinder.
156 */
157 class PipelineDescriptorSetBinder final : public IPipelineDescriptorSetBinder {
158 public:
159 PipelineDescriptorSetBinder(const PipelineLayout& pipelineLayout,
160 const BASE_NS::array_view<const RenderHandle> handles,
161 const BASE_NS::array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings);
162 PipelineDescriptorSetBinder(const PipelineLayout& pipelineLayout,
163 const BASE_NS::array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings);
164 ~PipelineDescriptorSetBinder() = default;
165
166 void ClearBindings() override;
167
168 RenderHandle GetDescriptorSetHandle(const uint32_t set) const override;
169 DescriptorSetLayoutBindingResources GetDescriptorSetLayoutBindingResources(const uint32_t set) const override;
170 bool GetPipelineDescriptorSetLayoutBindingValidity() const override;
171
172 uint32_t GetDescriptorSetCount() const override;
173 BASE_NS::array_view<const uint32_t> GetSetIndices() const override;
174 BASE_NS::array_view<const RenderHandle> GetDescriptorSetHandles() const override;
175
176 uint32_t GetFirstSet() const override;
177 BASE_NS::array_view<const RenderHandle> GetDescriptorSetHandles(
178 const uint32_t beginSet, const uint32_t count) const override;
179
180 void BindBuffer(const uint32_t set, const uint32_t binding, const BindableBuffer& resource,
181 const AdditionalDescriptorFlags flags) override;
182 void BindBuffer(const uint32_t set, const uint32_t binding, const BindableBuffer& resource) override;
183 void BindBuffers(
184 const uint32_t set, const uint32_t binding, const BASE_NS::array_view<const BindableBuffer> resources) override;
185
186 void BindImage(const uint32_t set, const uint32_t binding, const BindableImage& resource,
187 const AdditionalDescriptorFlags flags) override;
188 void BindImage(const uint32_t set, const uint32_t binding, const BindableImage& resource) override;
189 void BindImages(
190 const uint32_t set, const uint32_t binding, const BASE_NS::array_view<const BindableImage> resources) override;
191
192 void BindSampler(const uint32_t set, const uint32_t binding, const BindableSampler& resource,
193 const AdditionalDescriptorFlags flags) override;
194 void BindSampler(const uint32_t set, const uint32_t binding, const BindableSampler& resource) override;
195 void BindSamplers(const uint32_t set, const uint32_t binding,
196 const BASE_NS::array_view<const BindableSampler> resources) override;
197
198 void PrintPipelineDescriptorSetLayoutBindingValidation() const override;
199
200 protected:
201 void Destroy() override;
202
203 private:
204 // binder can be created without valid handles
205 void Init(const PipelineLayout& pipelineLayout, const BASE_NS::array_view<const RenderHandle> handles,
206 const BASE_NS::array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings, bool validHandles);
207
208 // set -> actual vector index
209 uint32_t setToBinderIndex_[PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT] { ~0u, ~0u, ~0u, ~0u };
210
211 BASE_NS::vector<DescriptorSetBinder> descriptorSetBinders_;
212
213 BASE_NS::vector<uint32_t> setIndices_;
214 BASE_NS::vector<RenderHandle> descriptorSetHandles_;
215 };
216 RENDER_END_NAMESPACE()
217
218 #endif // CORE__RENDER__PIPELINE_DESCRIPTOR_SET_BINDER_H
219