1 // Copyright 2021 The Tint 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 SRC_TRANSFORM_ARRAY_LENGTH_FROM_UNIFORM_H_ 16 #define SRC_TRANSFORM_ARRAY_LENGTH_FROM_UNIFORM_H_ 17 18 #include <unordered_map> 19 #include <unordered_set> 20 21 #include "src/sem/binding_point.h" 22 #include "src/transform/transform.h" 23 24 namespace tint { 25 26 // Forward declarations 27 class CloneContext; 28 29 namespace transform { 30 31 /// ArrayLengthFromUniform is a transform that implements calls to arrayLength() 32 /// by calculating the length from the total size of the storage buffer, which 33 /// is received via a uniform buffer. 34 /// 35 /// The generated uniform buffer will have the form: 36 /// ``` 37 /// [[block]] 38 /// struct buffer_size_struct { 39 /// buffer_size : array<u32, 8>; 40 /// }; 41 /// 42 /// [[group(0), binding(30)]] 43 /// var<uniform> buffer_size_ubo : buffer_size_struct; 44 /// ``` 45 /// The binding group and number used for this uniform buffer is provided via 46 /// the `Config` transform input. The `Config` struct also defines the mapping 47 /// from a storage buffer's `BindingPoint` to the array index that will be used 48 /// to get the size of that buffer. 49 /// 50 /// This transform assumes that the `SimplifyPointers` 51 /// transforms have been run before it so that arguments to the arrayLength 52 /// builtin always have the form `&resource.array`. 53 class ArrayLengthFromUniform 54 : public Castable<ArrayLengthFromUniform, Transform> { 55 public: 56 /// Constructor 57 ArrayLengthFromUniform(); 58 /// Destructor 59 ~ArrayLengthFromUniform() override; 60 61 /// Configuration options for the ArrayLengthFromUniform transform. 62 struct Config : public Castable<Data, transform::Data> { 63 /// Constructor 64 /// @param ubo_bp the binding point to use for the generated uniform buffer. 65 explicit Config(sem::BindingPoint ubo_bp); 66 67 /// Copy constructor 68 Config(const Config&); 69 70 /// Copy assignment 71 /// @return this Config 72 Config& operator=(const Config&); 73 74 /// Destructor 75 ~Config() override; 76 77 /// The binding point to use for the generated uniform buffer. 78 sem::BindingPoint ubo_binding; 79 80 /// The mapping from binding point to the index for the buffer size lookup. 81 std::unordered_map<sem::BindingPoint, uint32_t> bindpoint_to_size_index; 82 }; 83 84 /// Information produced about what the transform did. 85 struct Result : public Castable<Result, transform::Data> { 86 /// Constructor 87 /// @param used_size_indices Indices into the UBO that are statically used. 88 explicit Result(std::unordered_set<uint32_t> used_size_indices); 89 90 /// Copy constructor 91 Result(const Result&); 92 93 /// Destructor 94 ~Result() override; 95 96 /// Indices into the UBO that are statically used. 97 const std::unordered_set<uint32_t> used_size_indices; 98 }; 99 100 protected: 101 /// Runs the transform using the CloneContext built for transforming a 102 /// program. Run() is responsible for calling Clone() on the CloneContext. 103 /// @param ctx the CloneContext primed with the input program and 104 /// ProgramBuilder 105 /// @param inputs optional extra transform-specific input data 106 /// @param outputs optional extra transform-specific output data 107 void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) override; 108 }; 109 110 } // namespace transform 111 } // namespace tint 112 113 #endif // SRC_TRANSFORM_ARRAY_LENGTH_FROM_UNIFORM_H_ 114