• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_CANONICALIZE_ENTRY_POINT_IO_H_
16 #define SRC_TRANSFORM_CANONICALIZE_ENTRY_POINT_IO_H_
17 
18 #include "src/transform/transform.h"
19 
20 namespace tint {
21 namespace transform {
22 
23 /// CanonicalizeEntryPointIO is a transform used to rewrite shader entry point
24 /// interfaces into a form that the generators can handle. Each entry point
25 /// function is stripped of all shader IO attributes and wrapped in a function
26 /// that provides the shader interface.
27 /// The transform config determines whether to use global variables, structures,
28 /// or parameters for the shader inputs and outputs, and optionally adds
29 /// additional builtins to the shader interface.
30 ///
31 /// Before:
32 /// ```
33 /// struct Locations{
34 ///   [[location(1)]] loc1 : f32;
35 ///   [[location(2)]] loc2 : vec4<u32>;
36 /// };
37 ///
38 /// [[stage(fragment)]]
39 /// fn frag_main([[builtin(position)]] coord : vec4<f32>,
40 ///              locations : Locations) -> [[location(0)]] f32 {
41 ///   if (coord.w > 1.0) {
42 ///     return 0.0;
43 ///   }
44 ///   var col : f32 = (coord.x * locations.loc1);
45 ///   return col;
46 /// }
47 /// ```
48 ///
49 /// After (using structures for all parameters):
50 /// ```
51 /// struct Locations{
52 ///   loc1 : f32;
53 ///   loc2 : vec4<u32>;
54 /// };
55 ///
56 /// struct frag_main_in {
57 ///   [[builtin(position)]] coord : vec4<f32>;
58 ///   [[location(1)]] loc1 : f32;
59 ///   [[location(2)]] loc2 : vec4<u32>
60 /// };
61 ///
62 /// struct frag_main_out {
63 ///   [[location(0)]] loc0 : f32;
64 /// };
65 ///
66 /// fn frag_main_inner(coord : vec4<f32>,
67 ///                    locations : Locations) -> f32 {
68 ///   if (coord.w > 1.0) {
69 ///     return 0.0;
70 ///   }
71 ///   var col : f32 = (coord.x * locations.loc1);
72 ///   return col;
73 /// }
74 ///
75 /// [[stage(fragment)]]
76 /// fn frag_main(in : frag_main_in) -> frag_main_out {
77 ///   let inner_retval = frag_main_inner(in.coord, Locations(in.loc1, in.loc2));
78 ///   var wrapper_result : frag_main_out;
79 ///   wrapper_result.loc0 = inner_retval;
80 ///   return wrapper_result;
81 /// }
82 /// ```
83 class CanonicalizeEntryPointIO
84     : public Castable<CanonicalizeEntryPointIO, Transform> {
85  public:
86   /// ShaderStyle is an enumerator of different ways to emit shader IO.
87   enum class ShaderStyle {
88     /// Target SPIR-V (using global variables).
89     kSpirv,
90     /// Target MSL (using non-struct function parameters for builtins).
91     kMsl,
92     /// Target HLSL (using structures for all IO).
93     kHlsl,
94   };
95 
96   /// Configuration options for the transform.
97   struct Config : public Castable<Config, Data> {
98     /// Constructor
99     /// @param style the approach to use for emitting shader IO.
100     /// @param sample_mask an optional sample mask to combine with shader masks
101     /// @param emit_vertex_point_size `true` to generate a pointsize builtin
102     explicit Config(ShaderStyle style,
103                     uint32_t sample_mask = 0xFFFFFFFF,
104                     bool emit_vertex_point_size = false);
105 
106     /// Copy constructor
107     Config(const Config&);
108 
109     /// Destructor
110     ~Config() override;
111 
112     /// The approach to use for emitting shader IO.
113     const ShaderStyle shader_style;
114 
115     /// A fixed sample mask to combine into masks produced by fragment shaders.
116     const uint32_t fixed_sample_mask;
117 
118     /// Set to `true` to generate a pointsize builtin and have it set to 1.0
119     /// from all vertex shaders in the module.
120     const bool emit_vertex_point_size;
121   };
122 
123   /// Constructor
124   CanonicalizeEntryPointIO();
125   ~CanonicalizeEntryPointIO() override;
126 
127  protected:
128   /// Runs the transform using the CloneContext built for transforming a
129   /// program. Run() is responsible for calling Clone() on the CloneContext.
130   /// @param ctx the CloneContext primed with the input program and
131   /// ProgramBuilder
132   /// @param inputs optional extra transform-specific input data
133   /// @param outputs optional extra transform-specific output data
134   void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs) override;
135 
136   struct State;
137 };
138 
139 }  // namespace transform
140 }  // namespace tint
141 
142 #endif  // SRC_TRANSFORM_CANONICALIZE_ENTRY_POINT_IO_H_
143