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_NODECONTEXT_PIPELINE_DESCRIPTOR_SET_BINDER_H
17 #define RENDER_NODECONTEXT_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(
91 RenderHandle handle, BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings);
92 explicit DescriptorSetBinder(BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings);
93 ~DescriptorSetBinder() override = default;
94
95 void ClearBindings() override;
96 RenderHandle GetDescriptorSetHandle() const override;
97 DescriptorSetLayoutBindingResources GetDescriptorSetLayoutBindingResources() const override;
98
99 bool GetDescriptorSetLayoutBindingValidity() const override;
100 void PrintDescriptorSetLayoutBindingValidation() const override;
101
102 // all must call this
103 void BindBuffer(uint32_t binding, const BindableBuffer& resource, AdditionalDescriptorFlags flags) override;
104 void BindBuffer(uint32_t binding, const BindableBuffer& resource) override;
105 void BindBuffer(uint32_t binding, RenderHandle handle, uint32_t byteOffset) override;
106 void BindBuffer(uint32_t binding, RenderHandle handle, uint32_t byteOffset, uint32_t byteSize) override;
107 // for descriptor array binding
108 void BindBuffers(uint32_t binding, BASE_NS::array_view<const BindableBuffer> resources) override;
109
110 // all must call this
111 void BindImage(uint32_t binding, const BindableImage& resource, AdditionalDescriptorFlags flags) override;
112 void BindImage(uint32_t binding, const BindableImage& resource) override;
113 void BindImage(uint32_t binding, RenderHandle handle) override;
114 void BindImage(uint32_t binding, RenderHandle handle, RenderHandle samplerHandle) override;
115 // for descriptor array binding
116 void BindImages(uint32_t binding, BASE_NS::array_view<const BindableImage> resources) override;
117
118 // all must call this
119 void BindSampler(uint32_t binding, const BindableSampler& resource, AdditionalDescriptorFlags flags) override;
120 void BindSampler(uint32_t binding, const BindableSampler& resource) override;
121 void BindSampler(uint32_t binding, RenderHandle handle) override;
122 // for descriptor array binding
123 void BindSamplers(uint32_t binding, BASE_NS::array_view<const BindableSampler> resources) override;
124
125 protected:
126 void Destroy() override;
127
128 private:
129 void Init(BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings);
130 void InitFillBindings(BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings,
131 uint32_t bufferCount, uint32_t imageCount, uint32_t samplerCount);
132
133 RenderHandle handle_;
134 BASE_NS::vector<DescriptorSetLayoutBindingResource> bindings_;
135
136 BASE_NS::vector<BufferDescriptor> buffers_;
137 BASE_NS::vector<ImageDescriptor> images_;
138 BASE_NS::vector<SamplerDescriptor> samplers_;
139
140 // accesses array with binding number and retuns index;
141 PLUGIN_STATIC_ASSERT(PipelineLayoutConstants::MAX_DESCRIPTOR_SET_BINDING_COUNT == 16u);
142 uint8_t bindingToIndex_[PipelineLayoutConstants::MAX_DESCRIPTOR_SET_BINDING_COUNT] { 16, 16, 16, 16, 16, 16, 16, 16,
143 16, 16, 16, 16, 16, 16, 16, 16 };
144 uint32_t maxBindingCount_ { 0u };
145
146 uint32_t descriptorBindingMask_ { 0 };
147 uint32_t bindingMask_ { 0 };
148 };
149
150 /** PipelineDescriptorSetBinder.
151 */
152 class PipelineDescriptorSetBinder final : public IPipelineDescriptorSetBinder {
153 public:
154 PipelineDescriptorSetBinder(const PipelineLayout& pipelineLayout, BASE_NS::array_view<const RenderHandle> handles,
155 BASE_NS::array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings);
156 PipelineDescriptorSetBinder(const PipelineLayout& pipelineLayout,
157 BASE_NS::array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings);
158 ~PipelineDescriptorSetBinder() = default;
159
160 void ClearBindings() override;
161
162 RenderHandle GetDescriptorSetHandle(uint32_t set) const override;
163 DescriptorSetLayoutBindingResources GetDescriptorSetLayoutBindingResources(uint32_t set) const override;
164 bool GetPipelineDescriptorSetLayoutBindingValidity() const override;
165
166 uint32_t GetDescriptorSetCount() const override;
167 BASE_NS::array_view<const uint32_t> GetSetIndices() const override;
168 BASE_NS::array_view<const RenderHandle> GetDescriptorSetHandles() const override;
169
170 uint32_t GetFirstSet() const override;
171 BASE_NS::array_view<const RenderHandle> GetDescriptorSetHandles(uint32_t beginSet, uint32_t count) const override;
172
173 void BindBuffer(
174 uint32_t set, uint32_t binding, const BindableBuffer& resource, AdditionalDescriptorFlags flags) override;
175 void BindBuffer(uint32_t set, uint32_t binding, const BindableBuffer& resource) override;
176 void BindBuffers(uint32_t set, uint32_t binding, BASE_NS::array_view<const BindableBuffer> resources) override;
177
178 void BindImage(
179 uint32_t set, uint32_t binding, const BindableImage& resource, AdditionalDescriptorFlags flags) override;
180 void BindImage(uint32_t set, uint32_t binding, const BindableImage& resource) override;
181 void BindImages(uint32_t set, uint32_t binding, BASE_NS::array_view<const BindableImage> resources) override;
182
183 void BindSampler(
184 uint32_t set, uint32_t binding, const BindableSampler& resource, AdditionalDescriptorFlags flags) override;
185 void BindSampler(uint32_t set, uint32_t binding, const BindableSampler& resource) override;
186 void BindSamplers(uint32_t set, uint32_t binding, BASE_NS::array_view<const BindableSampler> resources) override;
187
188 void PrintPipelineDescriptorSetLayoutBindingValidation() const override;
189
190 protected:
191 void Destroy() override;
192
193 private:
194 // binder can be created without valid handles
195 void Init(const PipelineLayout& pipelineLayout, BASE_NS::array_view<const RenderHandle> handles,
196 BASE_NS::array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings, bool validHandles);
197
198 // set -> actual vector index
199 uint32_t setToBinderIndex_[PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT] { ~0u, ~0u, ~0u, ~0u };
200
201 BASE_NS::vector<DescriptorSetBinder> descriptorSetBinders_;
202
203 BASE_NS::vector<uint32_t> setIndices_;
204 BASE_NS::vector<RenderHandle> descriptorSetHandles_;
205 };
206 RENDER_END_NAMESPACE()
207
208 #endif // RENDER_NODECONTEXT_PIPELINE_DESCRIPTOR_SET_BINDER_H
209