Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
code_gen_template.h
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <string_view>
6
7namespace impeller {
8namespace compiler {
9
10constexpr std::string_view kReflectionHeaderTemplate =
11 R"~~(// THIS FILE IS GENERATED BY impellerc.
12// DO NOT EDIT OR CHECK THIS INTO SOURCE CONTROL
13
14#pragma once
15
16{# Note: The nogncheck decorations are only to make GN not mad at the template#}
17{# this file is generated from. There are no GN rule violations in the generated#}
18{# file itself and the no-check declarations will be stripped in generated files.#}
19#include "impeller/core/buffer_view.h" {# // nogncheck #}
20
21#include "impeller/core/sampler.h" {# // nogncheck #}
22
23#include "impeller/core/shader_types.h" {# // nogncheck #}
24
25#include "impeller/core/resource_binder.h" {# // nogncheck #}
26
27#include "impeller/core/texture.h" {# // nogncheck #}
28
29
30namespace impeller {
31
32struct {{camel_case(shader_name)}}{{camel_case(shader_stage)}}Shader {
33 // ===========================================================================
34 // Stage Info ================================================================
35 // ===========================================================================
36 static constexpr std::string_view kLabel = "{{camel_case(shader_name)}}";
37 static constexpr std::string_view kEntrypointName = "{{entrypoint}}";
38 static constexpr ShaderStage kShaderStage = {{to_shader_stage(shader_stage)}};
39 // The generator used to prepare these bindings. Metal generators may be used
40 // by GLES backends but GLES generators are unsuitable for the metal backend.
41 static constexpr std::string_view kGeneratorName = "{{get_generator_name()}}";
42{% if shader_stage == "compute" %}
43 // The workgroup (threadgroup) size declared by the shader. A dimension of 0
44 // is sized by a specialization constant and resolved by the backend at
45 // dispatch (for example, to the device maximum).
46 static constexpr std::array<uint32_t, 3> kWorkgroupSize = {
47 {{workgroup_size_x}}u, {{workgroup_size_y}}u, {{workgroup_size_z}}u};
48{% endif %}
49{% if length(struct_definitions) > 0 %}
50 // ===========================================================================
51 // Struct Definitions ========================================================
52 // ===========================================================================
53{% for def in struct_definitions %}
54
55{% if last(def.members).array_elements == 0 %}
56 template <size_t FlexCount>
57{% endif %}
58 struct {{def.name}} {
59{% for member in def.members %}
60{{" "}}{% if member.element_padding > 0 %}Padded<{{member.type}}, {{member.element_padding}}>{% else %}{{member.type}}{% endif %}{{" " + member.name}}{% if member.array_elements != "std::nullopt" %}[{% if member.array_elements == 0 %}FlexCount{% else %}{{member.array_elements}}{% endif %}]{% endif %}; // (offset {{member.offset}}, size {{member.byte_length}})
61{% endfor %}
62 }; // struct {{def.name}} (size {{def.byte_length}})
63{% endfor %}
64{% endif %}
65{% if length(buffers) > 0 %}
66
67 // ===========================================================================
68 // Stage Uniform & Storage Buffers ===========================================
69 // ===========================================================================
70{% for buffer in buffers %}
71
72 static constexpr auto kResource{{camel_case(buffer.name)}} = ShaderUniformSlot { // {{buffer.name}}
73 "{{buffer.name}}", // name
74 {{buffer.ext_res_0}}u, // ext_res_0
75 {{buffer.set}}u, // set
76 {{buffer.binding}}u, // binding
77 };
78 static ShaderMetadata kMetadata{{camel_case(buffer.name)}};
79{% endfor %}
80{% endif %}
81
82 // ===========================================================================
83 // Stage Inputs ==============================================================
84 // ===========================================================================
85{% for stage_input in stage_inputs %}
86 static constexpr auto kInput{{camel_case(stage_input.name)}} = ShaderStageIOSlot { // {{stage_input.name}}
87 "{{stage_input.name}}", // name
88 {{stage_input.location}}u, // attribute location
89 {{stage_input.descriptor_set}}u, // attribute set
90 {{stage_input.binding}}u, // attribute binding
91 {{stage_input.type.type_name}}, // type
92 {{stage_input.type.bit_width}}u, // bit width of type
93 {{stage_input.type.vec_size}}u, // vec size
94 {{stage_input.type.columns}}u, // number of columns
95 {{stage_input.offset}}u, // offset for interleaved layout
96 {{stage_input.relaxed_precision}}, // relaxed precision
97 };
98{% endfor %}
99
100 static constexpr std::array<const ShaderStageIOSlot*, {{length(stage_inputs)}}> kAllShaderStageInputs = {
101{% for stage_input in stage_inputs %}
102 &kInput{{camel_case(stage_input.name)}}, // {{stage_input.name}}
103{% endfor %}
104 };
105
106{% if shader_stage == "vertex" %}
107 static constexpr auto kInterleavedLayout = ShaderStageBufferLayout {
108{% if length(stage_inputs) > 0 %}
109 sizeof(PerVertexData), // stride for interleaved layout
110{% else %}
111 0u,
112{% endif %}
113 0u, // attribute binding
114 };
115 static constexpr std::array<const ShaderStageBufferLayout*, 1> kInterleavedBufferLayout = {
116 &kInterleavedLayout
117 };
118{% endif %}
119
120{% if length(sampled_images) > 0 %}
121 // ===========================================================================
122 // Sampled Images ============================================================
123 // ===========================================================================
124{% for sampled_image in sampled_images %}
125
126 static constexpr auto kResource{{camel_case(sampled_image.name)}} = SampledImageSlot { // {{sampled_image.name}}
127 "{{sampled_image.name}}", // name
128 {{sampled_image.ext_res_0}}u, // ext_res_0
129 {{sampled_image.set}}u, // set
130 {{sampled_image.binding}}u, // binding
131 };
132 static ShaderMetadata kMetadata{{camel_case(sampled_image.name)}};
133{% endfor %}
134{% endif %}
135 // ===========================================================================
136 // Stage Outputs =============================================================
137 // ===========================================================================
138{% for stage_output in stage_outputs %}
139 static constexpr auto kOutput{{camel_case(stage_output.name)}} = ShaderStageIOSlot { // {{stage_output.name}}
140 "{{stage_output.name}}", // name
141 {{stage_output.location}}u, // attribute location
142 {{stage_output.descriptor_set}}u, // attribute set
143 {{stage_output.binding}}u, // attribute binding
144 {{stage_output.type.type_name}}, // type
145 {{stage_output.type.bit_width}}u, // bit width of type
146 {{stage_output.type.vec_size}}u, // vec size
147 {{stage_output.type.columns}}u, // number of columns
148 {{stage_output.offset}}u, // offset for interleaved layout
149 {{stage_output.relaxed_precision}}, // relaxed precision
150 };
151{% endfor %}
152 static constexpr std::array<const ShaderStageIOSlot*, {{length(stage_outputs)}}> kAllShaderStageOutputs = {
153{% for stage_output in stage_outputs %}
154 &kOutput{{camel_case(stage_output.name)}}, // {{stage_output.name}}
155{% endfor %}
156 };
157
158 // ===========================================================================
159 // Resource Binding Utilities ================================================
160 // ===========================================================================
161
162{% for proto in bind_prototypes %}
163 /// {{proto.docstring}}
164 static {{proto.return_type}} Bind{{proto.name}}({% for arg in proto.args %}
165{{arg.type_name}} {{arg.argument_name}}{% if not loop.is_last %}, {% endif %}
166{% endfor %}) {
167 return {{ proto.args.0.argument_name }}.BindResource({% for arg in proto.args %}
168 {% if loop.is_first %}
169{{to_shader_stage(shader_stage)}}, {{ proto.descriptor_type }}, kResource{{ proto.name }}, &kMetadata{{ proto.name }}, {% else %}
170std::move({{ arg.argument_name }}){% if not loop.is_last %}, {% endif %}
171 {% endif %}
172 {% endfor %});
173 }
174
175{% endfor %}
176
177 // ===========================================================================
178 // Metadata for Vulkan =======================================================
179 // ===========================================================================
180 static constexpr std::array<DescriptorSetLayout,{{length(buffers)+length(sampled_images)+length(subpass_inputs)}}> kDescriptorSetLayouts{
181{% for subpass_input in subpass_inputs %}
182 DescriptorSetLayout{
183 {{subpass_input.binding}}, // binding = {{subpass_input.binding}}
184 {{subpass_input.descriptor_type}}, // descriptor_type = {{subpass_input.descriptor_type}}
185 {{to_shader_stage(shader_stage)}}, // shader_stage = {{to_shader_stage(shader_stage)}}
186 },
187{% endfor %}
188{% for buffer in buffers %}
189 DescriptorSetLayout{
190 {{buffer.binding}}, // binding = {{buffer.binding}}
191 {{buffer.descriptor_type}}, // descriptor_type = {{buffer.descriptor_type}}
192 {{to_shader_stage(shader_stage)}}, // shader_stage = {{to_shader_stage(shader_stage)}}
193 },
194{% endfor %}
195{% for sampled_image in sampled_images %}
196 DescriptorSetLayout{
197 {{sampled_image.binding}}, // binding = {{sampled_image.binding}}
198 {{sampled_image.descriptor_type}}, // descriptor_type = {{sampled_image.descriptor_type}}
199 {{to_shader_stage(shader_stage)}}, // shader_stage = {{to_shader_stage(shader_stage)}}
200 },
201{% endfor %}
202 };
203
204}; // struct {{camel_case(shader_name)}}{{camel_case(shader_stage)}}Shader
205
206} // namespace impeller
207)~~";
208
209constexpr std::string_view kReflectionCCTemplate =
210 R"~~(// THIS FILE IS GENERATED BY impellerc.
211// DO NOT EDIT OR CHECK THIS INTO SOURCE CONTROL
212
213#include "{{header_file_name}}"
214
215#include <type_traits>
216
217namespace impeller {
218
219using Shader = {{camel_case(shader_name)}}{{camel_case(shader_stage)}}Shader;
220
221{% for def in struct_definitions %}
222// Sanity checks for {{def.name}}
223{% if last(def.members).array_elements == 0 %}
224static_assert(std::is_standard_layout_v<Shader::{{def.name}}<0>>);
225{% for member in def.members %}
226static_assert(offsetof(Shader::{{def.name}}<0>, {{member.name}}) == {{member.offset}});
227{% endfor %}
228{% else %}
229static_assert(std::is_standard_layout_v<Shader::{{def.name}}>);
230static_assert(sizeof(Shader::{{def.name}}) == {{def.byte_length}});
231{% for member in def.members %}
232static_assert(offsetof(Shader::{{def.name}}, {{member.name}}) == {{member.offset}});
233{% endfor %}
234{% endif %}
235{% endfor %}
236
237{% for buffer in buffers %}
238ShaderMetadata Shader::kMetadata{{camel_case(buffer.name)}} = {
239 "{{buffer.name}}", // name
240 std::vector<ShaderStructMemberMetadata> {
241 {% for member in buffer.type.members %}
242 ShaderStructMemberMetadata {
243 /*type=*/{{ member.base_type }},
244 /*name=*/"{{ member.name }}",
245 /*offset=*/{{ member.offset }},
246 /*size=*/{{ member.size }},
247 /*byte_length=*/{{ member.byte_length }},
248 /*array_elements=*/{{ member.array_elements }},
249 /*float_type=*/{{ member.float_type }},
250 },
251 {% endfor %}
252 } // members
253};
254{% endfor %}
255
256{% for sampled_image in sampled_images %}
257ShaderMetadata Shader::kMetadata{{camel_case(sampled_image.name)}} = {
258 "{{sampled_image.name}}", // name
259 std::vector<ShaderStructMemberMetadata> {}, // 0 members
260};
261{% endfor %}
262
263} // namespace impeller
264)~~";
265
266} // namespace compiler
267} // namespace impeller
constexpr std::string_view kReflectionHeaderTemplate
constexpr std::string_view kReflectionCCTemplate