• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 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_INDIRECTDRAWMETADATA_H_
16 #define DAWNNATIVE_INDIRECTDRAWMETADATA_H_
17 
18 #include "common/NonCopyable.h"
19 #include "common/RefCounted.h"
20 #include "dawn_native/Buffer.h"
21 #include "dawn_native/CommandBufferStateTracker.h"
22 #include "dawn_native/Commands.h"
23 
24 #include <cstdint>
25 #include <map>
26 #include <set>
27 #include <utility>
28 #include <vector>
29 
30 namespace dawn_native {
31 
32     class RenderBundleBase;
33     struct CombinedLimits;
34 
35     // In the unlikely scenario that indirect offsets used over a single buffer span more than
36     // this length of the buffer, we split the validation work into multiple batches.
37     uint32_t ComputeMaxIndirectValidationBatchOffsetRange(const CombinedLimits& limits);
38 
39     // Metadata corresponding to the validation requirements of a single render pass. This metadata
40     // is accumulated while its corresponding render pass is encoded, and is later used to encode
41     // validation commands to be inserted into the command buffer just before the render pass's own
42     // commands.
43     class IndirectDrawMetadata : public NonCopyable {
44       public:
45         struct IndexedIndirectDraw {
46             uint64_t clientBufferOffset;
47             // This is a pointer to the command that should be populated with the validated
48             // indirect scratch buffer. It is only valid up until the encoded command buffer
49             // is submitted.
50             DrawIndexedIndirectCmd* cmd;
51         };
52 
53         struct IndexedIndirectValidationBatch {
54             uint64_t minOffset;
55             uint64_t maxOffset;
56             std::vector<IndexedIndirectDraw> draws;
57         };
58 
59         // Tracks information about every draw call in this render pass which uses the same indirect
60         // buffer and the same-sized index buffer. Calls are grouped by indirect offset ranges so
61         // that validation work can be chunked efficiently if necessary.
62         class IndexedIndirectBufferValidationInfo {
63           public:
64             explicit IndexedIndirectBufferValidationInfo(BufferBase* indirectBuffer);
65 
66             // Logs a new drawIndexedIndirect call for the render pass. `cmd` is updated with an
67             // assigned (and deferred) buffer ref and relative offset before returning.
68             void AddIndexedIndirectDraw(uint32_t maxDrawCallsPerIndirectValidationBatch,
69                                         uint32_t maxBatchOffsetRange,
70                                         IndexedIndirectDraw draw);
71 
72             // Adds draw calls from an already-computed batch, e.g. from a previously encoded
73             // RenderBundle. The added batch is merged into an existing batch if possible, otherwise
74             // it's added to mBatch.
75             void AddBatch(uint32_t maxDrawCallsPerIndirectValidationBatch,
76                           uint32_t maxBatchOffsetRange,
77                           const IndexedIndirectValidationBatch& batch);
78 
79             const std::vector<IndexedIndirectValidationBatch>& GetBatches() const;
80 
81           private:
82             Ref<BufferBase> mIndirectBuffer;
83 
84             // A list of information about validation batches that will need to be executed for the
85             // corresponding indirect buffer prior to a single render pass. These are kept sorted by
86             // minOffset and may overlap iff the number of offsets in one batch would otherwise
87             // exceed some large upper bound (roughly ~33M draw calls).
88             //
89             // Since the most common expected cases will overwhelmingly require only a single
90             // validation pass per render pass, this is optimized for efficient updates to a single
91             // batch rather than for efficient manipulation of a large number of batches.
92             std::vector<IndexedIndirectValidationBatch> mBatches;
93         };
94 
95         // Combination of an indirect buffer reference, and the number of addressable index buffer
96         // elements at the time of a draw call.
97         using IndexedIndirectConfig = std::pair<BufferBase*, uint64_t>;
98         using IndexedIndirectBufferValidationInfoMap =
99             std::map<IndexedIndirectConfig, IndexedIndirectBufferValidationInfo>;
100 
101         explicit IndirectDrawMetadata(const CombinedLimits& limits);
102         ~IndirectDrawMetadata();
103 
104         IndirectDrawMetadata(IndirectDrawMetadata&&);
105         IndirectDrawMetadata& operator=(IndirectDrawMetadata&&);
106 
107         IndexedIndirectBufferValidationInfoMap* GetIndexedIndirectBufferValidationInfo();
108 
109         void AddBundle(RenderBundleBase* bundle);
110         void AddIndexedIndirectDraw(wgpu::IndexFormat indexFormat,
111                                     uint64_t indexBufferSize,
112                                     BufferBase* indirectBuffer,
113                                     uint64_t indirectOffset,
114                                     DrawIndexedIndirectCmd* cmd);
115 
116       private:
117         IndexedIndirectBufferValidationInfoMap mIndexedIndirectBufferValidationInfo;
118         std::set<RenderBundleBase*> mAddedBundles;
119 
120         uint32_t mMaxDrawCallsPerBatch;
121         uint32_t mMaxBatchOffsetRange;
122     };
123 
124 }  // namespace dawn_native
125 
126 #endif  // DAWNNATIVE_INDIRECTDRAWMETADATA_H_
127