• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Dawn Authors
2 //
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 #ifndef DAWNNATIVE_BINDGROUPLAYOUT_H_
16 #define DAWNNATIVE_BINDGROUPLAYOUT_H_
17 
18 #include "common/Constants.h"
19 #include "common/Math.h"
20 #include "common/SlabAllocator.h"
21 #include "common/ityp_span.h"
22 #include "common/ityp_vector.h"
23 #include "dawn_native/BindingInfo.h"
24 #include "dawn_native/CachedObject.h"
25 #include "dawn_native/Error.h"
26 #include "dawn_native/Forward.h"
27 #include "dawn_native/ObjectBase.h"
28 
29 #include "dawn_native/dawn_platform.h"
30 
31 #include <bitset>
32 #include <map>
33 
34 namespace dawn_native {
35 
36     MaybeError ValidateBindGroupLayoutDescriptor(DeviceBase* device,
37                                                  const BindGroupLayoutDescriptor* descriptor,
38                                                  bool allowInternalBinding = false);
39 
40     // Bindings are specified as a |BindingNumber| in the BindGroupLayoutDescriptor.
41     // These numbers may be arbitrary and sparse. Internally, Dawn packs these numbers
42     // into a packed range of |BindingIndex| integers.
43     class BindGroupLayoutBase : public ApiObjectBase, public CachedObject {
44       public:
45         BindGroupLayoutBase(DeviceBase* device,
46                             const BindGroupLayoutDescriptor* descriptor,
47                             PipelineCompatibilityToken pipelineCompatibilityToken,
48                             ApiObjectBase::UntrackedByDeviceTag tag);
49         BindGroupLayoutBase(DeviceBase* device,
50                             const BindGroupLayoutDescriptor* descriptor,
51                             PipelineCompatibilityToken pipelineCompatibilityToken);
52         ~BindGroupLayoutBase() override;
53 
54         static BindGroupLayoutBase* MakeError(DeviceBase* device);
55 
56         ObjectType GetType() const override;
57 
58         // A map from the BindingNumber to its packed BindingIndex.
59         using BindingMap = std::map<BindingNumber, BindingIndex>;
60 
GetBindingInfo(BindingIndex bindingIndex)61         const BindingInfo& GetBindingInfo(BindingIndex bindingIndex) const {
62             ASSERT(!IsError());
63             ASSERT(bindingIndex < mBindingInfo.size());
64             return mBindingInfo[bindingIndex];
65         }
66         const BindingMap& GetBindingMap() const;
67         bool HasBinding(BindingNumber bindingNumber) const;
68         BindingIndex GetBindingIndex(BindingNumber bindingNumber) const;
69 
70         // Functions necessary for the unordered_set<BGLBase*>-based cache.
71         size_t ComputeContentHash() override;
72 
73         struct EqualityFunc {
74             bool operator()(const BindGroupLayoutBase* a, const BindGroupLayoutBase* b) const;
75         };
76 
77         BindingIndex GetBindingCount() const;
78         // Returns |BindingIndex| because buffers are packed at the front.
79         BindingIndex GetBufferCount() const;
80         // Returns |BindingIndex| because dynamic buffers are packed at the front.
81         BindingIndex GetDynamicBufferCount() const;
82         uint32_t GetUnverifiedBufferCount() const;
83 
84         // Used to get counts and validate them in pipeline layout creation. Other getters
85         // should be used to get typed integer counts.
86         const BindingCounts& GetBindingCountInfo() const;
87 
88         // Tests that the BindingInfo of two bind groups are equal,
89         // ignoring their compatibility groups.
90         bool IsLayoutEqual(const BindGroupLayoutBase* other,
91                            bool excludePipelineCompatibiltyToken = false) const;
92         PipelineCompatibilityToken GetPipelineCompatibilityToken() const;
93 
94         struct BufferBindingData {
95             uint64_t offset;
96             uint64_t size;
97         };
98 
99         struct BindingDataPointers {
100             ityp::span<BindingIndex, BufferBindingData> const bufferData = {};
101             ityp::span<BindingIndex, Ref<ObjectBase>> const bindings = {};
102             ityp::span<uint32_t, uint64_t> const unverifiedBufferSizes = {};
103         };
104 
105         // Compute the amount of space / alignment required to store bindings for a bind group of
106         // this layout.
107         size_t GetBindingDataSize() const;
GetBindingDataAlignment()108         static constexpr size_t GetBindingDataAlignment() {
109             static_assert(alignof(Ref<ObjectBase>) <= alignof(BufferBindingData), "");
110             return alignof(BufferBindingData);
111         }
112 
113         BindingDataPointers ComputeBindingDataPointers(void* dataStart) const;
114 
115         bool IsStorageBufferBinding(BindingIndex bindingIndex) const;
116 
117       protected:
118         // Constructor used only for mocking and testing.
119         BindGroupLayoutBase(DeviceBase* device);
120         void DestroyImpl() override;
121 
122         template <typename BindGroup>
MakeFrontendBindGroupAllocator(size_t size)123         SlabAllocator<BindGroup> MakeFrontendBindGroupAllocator(size_t size) {
124             return SlabAllocator<BindGroup>(
125                 size,  // bytes
126                 Align(sizeof(BindGroup), GetBindingDataAlignment()) + GetBindingDataSize(),  // size
127                 std::max(alignof(BindGroup), GetBindingDataAlignment())  // alignment
128             );
129         }
130 
131       private:
132         BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag);
133 
134         BindingCounts mBindingCounts = {};
135         ityp::vector<BindingIndex, BindingInfo> mBindingInfo;
136 
137         // Map from BindGroupLayoutEntry.binding to packed indices.
138         BindingMap mBindingMap;
139 
140         // Non-0 if this BindGroupLayout was created as part of a default PipelineLayout.
141         const PipelineCompatibilityToken mPipelineCompatibilityToken =
142             PipelineCompatibilityToken(0);
143     };
144 
145 }  // namespace dawn_native
146 
147 #endif  // DAWNNATIVE_BINDGROUPLAYOUT_H_
148