• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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_FIRST_INDEX_OFFSET_H_
16 #define SRC_TRANSFORM_FIRST_INDEX_OFFSET_H_
17 
18 #include "src/transform/transform.h"
19 
20 namespace tint {
21 namespace transform {
22 
23 /// Adds firstVertex/Instance (injected via root constants) to
24 /// vertex/instance index builtins.
25 ///
26 /// This transform assumes that Name transform has been run before.
27 ///
28 /// Unlike other APIs, D3D always starts vertex and instance numbering at 0,
29 /// regardless of the firstVertex/Instance value specified. This transformer
30 /// adds the value of firstVertex/Instance to each builtin. This action is
31 /// performed by adding a new constant equal to original builtin +
32 /// firstVertex/Instance to each function that references one of these builtins.
33 ///
34 /// Note that D3D does not have any semantics for firstVertex/Instance.
35 /// Therefore, these values must by passed to the shader.
36 ///
37 /// Before:
38 ///   [[builtin(vertex_index)]] var<in> vert_idx : u32;
39 ///   fn func() -> u32 {
40 ///     return vert_idx;
41 ///   }
42 ///
43 /// After:
44 ///   [[block]]
45 ///   struct TintFirstIndexOffsetData {
46 ///     tint_first_vertex_index : u32;
47 ///     tint_first_instance_index : u32;
48 ///   };
49 ///   [[builtin(vertex_index)]] var<in> tint_first_index_offset_vert_idx : u32;
50 ///   [[binding(N), group(M)]] var<uniform> tint_first_index_data :
51 ///                                                    TintFirstIndexOffsetData;
52 ///   fn func() -> u32 {
53 ///     const vert_idx = (tint_first_index_offset_vert_idx +
54 ///                       tint_first_index_data.tint_first_vertex_index);
55 ///     return vert_idx;
56 ///   }
57 ///
58 class FirstIndexOffset : public Castable<FirstIndexOffset, Transform> {
59  public:
60   /// BindingPoint is consumed by the FirstIndexOffset transform.
61   /// BindingPoint specifies the binding point of the first index uniform
62   /// buffer.
63   struct BindingPoint : public Castable<BindingPoint, transform::Data> {
64     /// Constructor
65     BindingPoint();
66 
67     /// Constructor
68     /// @param b the binding index
69     /// @param g the binding group
70     BindingPoint(uint32_t b, uint32_t g);
71 
72     /// Destructor
73     ~BindingPoint() override;
74 
75     /// [[binding()]] for the first vertex / first instance uniform buffer
76     uint32_t binding = 0;
77     /// [[group()]] for the first vertex / first instance uniform buffer
78     uint32_t group = 0;
79   };
80 
81   /// Data is outputted by the FirstIndexOffset transform.
82   /// Data holds information about shader usage and constant buffer offsets.
83   struct Data : public Castable<Data, transform::Data> {
84     /// Constructor
85     /// @param has_vtx_index True if the shader uses vertex_index
86     /// @param has_inst_index True if the shader uses instance_index
87     /// @param first_vtx_offset Offset of first vertex into constant buffer
88     /// @param first_inst_offset Offset of first instance into constant buffer
89     Data(bool has_vtx_index,
90          bool has_inst_index,
91          uint32_t first_vtx_offset,
92          uint32_t first_inst_offset);
93 
94     /// Copy constructor
95     Data(const Data&);
96 
97     /// Destructor
98     ~Data() override;
99 
100     /// True if the shader uses vertex_index
101     const bool has_vertex_index;
102     /// True if the shader uses instance_index
103     const bool has_instance_index;
104     /// Offset of first vertex into constant buffer
105     const uint32_t first_vertex_offset;
106     /// Offset of first instance into constant buffer
107     const uint32_t first_instance_offset;
108   };
109 
110   /// Constructor
111   FirstIndexOffset();
112   /// Destructor
113   ~FirstIndexOffset() override;
114 
115  protected:
116   /// Runs the transform using the CloneContext built for transforming a
117   /// program. Run() is responsible for calling Clone() on the CloneContext.
118   /// @param ctx the CloneContext primed with the input program and
119   /// ProgramBuilder
120   /// @param inputs optional extra transform-specific input data
121   /// @param outputs optional extra transform-specific output data
122   void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) override;
123 
124  private:
125   uint32_t binding_ = 0;
126   uint32_t group_ = 0;
127 };
128 
129 }  // namespace transform
130 }  // namespace tint
131 
132 #endif  // SRC_TRANSFORM_FIRST_INDEX_OFFSET_H_
133