Flutter Engine
 
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 length(struct_definitions) > 0 %}
43 // ===========================================================================
44 // Struct Definitions ========================================================
45 // ===========================================================================
46{% for def in struct_definitions %}
47
48{% if last(def.members).array_elements == 0 %}
49 template <size_t FlexCount>
50{% endif %}
51 struct {{def.name}} {
52{% for member in def.members %}
53{{" "}}{% 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}})
54{% endfor %}
55 }; // struct {{def.name}} (size {{def.byte_length}})
56{% endfor %}
57{% endif %}
58{% if length(buffers) > 0 %}
59
60 // ===========================================================================
61 // Stage Uniform & Storage Buffers ===========================================
62 // ===========================================================================
63{% for buffer in buffers %}
64
65 static constexpr auto kResource{{camel_case(buffer.name)}} = ShaderUniformSlot { // {{buffer.name}}
66 "{{buffer.name}}", // name
67 {{buffer.ext_res_0}}u, // ext_res_0
68 {{buffer.set}}u, // set
69 {{buffer.binding}}u, // binding
70 };
71 static ShaderMetadata kMetadata{{camel_case(buffer.name)}};
72{% endfor %}
73{% endif %}
74
75 // ===========================================================================
76 // Stage Inputs ==============================================================
77 // ===========================================================================
78{% for stage_input in stage_inputs %}
79 static constexpr auto kInput{{camel_case(stage_input.name)}} = ShaderStageIOSlot { // {{stage_input.name}}
80 "{{stage_input.name}}", // name
81 {{stage_input.location}}u, // attribute location
82 {{stage_input.descriptor_set}}u, // attribute set
83 {{stage_input.binding}}u, // attribute binding
84 {{stage_input.type.type_name}}, // type
85 {{stage_input.type.bit_width}}u, // bit width of type
86 {{stage_input.type.vec_size}}u, // vec size
87 {{stage_input.type.columns}}u, // number of columns
88 {{stage_input.offset}}u, // offset for interleaved layout
89 {{stage_input.relaxed_precision}}, // relaxed precision
90 };
91{% endfor %}
92
93 static constexpr std::array<const ShaderStageIOSlot*, {{length(stage_inputs)}}> kAllShaderStageInputs = {
94{% for stage_input in stage_inputs %}
95 &kInput{{camel_case(stage_input.name)}}, // {{stage_input.name}}
96{% endfor %}
97 };
98
99{% if shader_stage == "vertex" %}
100 static constexpr auto kInterleavedLayout = ShaderStageBufferLayout {
101{% if length(stage_inputs) > 0 %}
102 sizeof(PerVertexData), // stride for interleaved layout
103{% else %}
104 0u,
105{% endif %}
106 0u, // attribute binding
107 };
108 static constexpr std::array<const ShaderStageBufferLayout*, 1> kInterleavedBufferLayout = {
109 &kInterleavedLayout
110 };
111{% endif %}
112
113{% if length(sampled_images) > 0 %}
114 // ===========================================================================
115 // Sampled Images ============================================================
116 // ===========================================================================
117{% for sampled_image in sampled_images %}
118
119 static constexpr auto kResource{{camel_case(sampled_image.name)}} = SampledImageSlot { // {{sampled_image.name}}
120 "{{sampled_image.name}}", // name
121 {{sampled_image.ext_res_0}}u, // ext_res_0
122 {{sampled_image.set}}u, // set
123 {{sampled_image.binding}}u, // binding
124 };
125 static ShaderMetadata kMetadata{{camel_case(sampled_image.name)}};
126{% endfor %}
127{% endif %}
128 // ===========================================================================
129 // Stage Outputs =============================================================
130 // ===========================================================================
131{% for stage_output in stage_outputs %}
132 static constexpr auto kOutput{{camel_case(stage_output.name)}} = ShaderStageIOSlot { // {{stage_output.name}}
133 "{{stage_output.name}}", // name
134 {{stage_output.location}}u, // attribute location
135 {{stage_output.descriptor_set}}u, // attribute set
136 {{stage_output.binding}}u, // attribute binding
137 {{stage_output.type.type_name}}, // type
138 {{stage_output.type.bit_width}}u, // bit width of type
139 {{stage_output.type.vec_size}}u, // vec size
140 {{stage_output.type.columns}}u, // number of columns
141 {{stage_output.offset}}u, // offset for interleaved layout
142 {{stage_output.relaxed_precision}}, // relaxed precision
143 };
144{% endfor %}
145 static constexpr std::array<const ShaderStageIOSlot*, {{length(stage_outputs)}}> kAllShaderStageOutputs = {
146{% for stage_output in stage_outputs %}
147 &kOutput{{camel_case(stage_output.name)}}, // {{stage_output.name}}
148{% endfor %}
149 };
150
151 // ===========================================================================
152 // Resource Binding Utilities ================================================
153 // ===========================================================================
154
155{% for proto in bind_prototypes %}
156 /// {{proto.docstring}}
157 static {{proto.return_type}} Bind{{proto.name}}({% for arg in proto.args %}
158{{arg.type_name}} {{arg.argument_name}}{% if not loop.is_last %}, {% endif %}
159{% endfor %}) {
160 return {{ proto.args.0.argument_name }}.BindResource({% for arg in proto.args %}
161 {% if loop.is_first %}
162{{to_shader_stage(shader_stage)}}, {{ proto.descriptor_type }}, kResource{{ proto.name }}, &kMetadata{{ proto.name }}, {% else %}
163std::move({{ arg.argument_name }}){% if not loop.is_last %}, {% endif %}
164 {% endif %}
165 {% endfor %});
166 }
167
168{% endfor %}
169
170 // ===========================================================================
171 // Metadata for Vulkan =======================================================
172 // ===========================================================================
173 static constexpr std::array<DescriptorSetLayout,{{length(buffers)+length(sampled_images)+length(subpass_inputs)}}> kDescriptorSetLayouts{
174{% for subpass_input in subpass_inputs %}
175 DescriptorSetLayout{
176 {{subpass_input.binding}}, // binding = {{subpass_input.binding}}
177 {{subpass_input.descriptor_type}}, // descriptor_type = {{subpass_input.descriptor_type}}
178 {{to_shader_stage(shader_stage)}}, // shader_stage = {{to_shader_stage(shader_stage)}}
179 },
180{% endfor %}
181{% for buffer in buffers %}
182 DescriptorSetLayout{
183 {{buffer.binding}}, // binding = {{buffer.binding}}
184 {{buffer.descriptor_type}}, // descriptor_type = {{buffer.descriptor_type}}
185 {{to_shader_stage(shader_stage)}}, // shader_stage = {{to_shader_stage(shader_stage)}}
186 },
187{% endfor %}
188{% for sampled_image in sampled_images %}
189 DescriptorSetLayout{
190 {{sampled_image.binding}}, // binding = {{sampled_image.binding}}
191 {{sampled_image.descriptor_type}}, // descriptor_type = {{sampled_image.descriptor_type}}
192 {{to_shader_stage(shader_stage)}}, // shader_stage = {{to_shader_stage(shader_stage)}}
193 },
194{% endfor %}
195 };
196
197}; // struct {{camel_case(shader_name)}}{{camel_case(shader_stage)}}Shader
198
199} // namespace impeller
200)~~";
201
202constexpr std::string_view kReflectionCCTemplate =
203 R"~~(// THIS FILE IS GENERATED BY impellerc.
204// DO NOT EDIT OR CHECK THIS INTO SOURCE CONTROL
205
206#include "{{header_file_name}}"
207
208#include <type_traits>
209
210namespace impeller {
211
212using Shader = {{camel_case(shader_name)}}{{camel_case(shader_stage)}}Shader;
213
214{% for def in struct_definitions %}
215// Sanity checks for {{def.name}}
216{% if last(def.members).array_elements == 0 %}
217static_assert(std::is_standard_layout_v<Shader::{{def.name}}<0>>);
218{% for member in def.members %}
219static_assert(offsetof(Shader::{{def.name}}<0>, {{member.name}}) == {{member.offset}});
220{% endfor %}
221{% else %}
222static_assert(std::is_standard_layout_v<Shader::{{def.name}}>);
223static_assert(sizeof(Shader::{{def.name}}) == {{def.byte_length}});
224{% for member in def.members %}
225static_assert(offsetof(Shader::{{def.name}}, {{member.name}}) == {{member.offset}});
226{% endfor %}
227{% endif %}
228{% endfor %}
229
230{% for buffer in buffers %}
231ShaderMetadata Shader::kMetadata{{camel_case(buffer.name)}} = {
232 "{{buffer.name}}", // name
233 std::vector<ShaderStructMemberMetadata> {
234 {% for member in buffer.type.members %}
235 ShaderStructMemberMetadata {
236 {{ member.base_type }}, // type
237 "{{ member.name }}", // name
238 {{ member.offset }}, // offset
239 {{ member.size }}, // size
240 {{ member.byte_length }}, // byte_length
241 {{ member.array_elements }}, // array_elements
242 },
243 {% endfor %}
244 } // members
245};
246{% endfor %}
247
248{% for sampled_image in sampled_images %}
249ShaderMetadata Shader::kMetadata{{camel_case(sampled_image.name)}} = {
250 "{{sampled_image.name}}", // name
251 std::vector<ShaderStructMemberMetadata> {}, // 0 members
252};
253{% endfor %}
254
255} // namespace impeller
256)~~";
257
258} // namespace compiler
259} // namespace impeller
constexpr std::string_view kReflectionHeaderTemplate
constexpr std::string_view kReflectionCCTemplate