Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
reflector.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#ifndef FLUTTER_IMPELLER_COMPILER_REFLECTOR_H_
6#define FLUTTER_IMPELLER_COMPILER_REFLECTOR_H_
7
8#include <cstdint>
9#include <memory>
10#include <optional>
11
12#include "flutter/fml/macros.h"
13#include "flutter/fml/mapping.h"
14#include "fml/logging.h"
19#include "inja/inja.hpp"
20#include "spirv_common.hpp"
21#include "spirv_msl.hpp"
22#include "spirv_parser.hpp"
23
24namespace impeller {
25namespace compiler {
26
28 // Runtime stages on Vulkan use this information to validate that a struct
29 // only contains floats and encode where padding gets inserted.
30 enum class UnderlyingType {
32 kFloat,
33 kOther,
34 };
35
36 std::string type;
37 spirv_cross::SPIRType::BaseType base_type;
38 std::string name;
39 size_t offset = 0u;
40 size_t size = 0u;
41 size_t byte_length = 0u;
42 std::optional<size_t> array_elements = std::nullopt;
43 size_t element_padding = 0u;
45
46 static std::string BaseTypeToString(spirv_cross::SPIRType::BaseType type) {
47 using Type = spirv_cross::SPIRType::BaseType;
48 switch (type) {
49 case Type::Void:
50 return "ShaderType::kVoid";
51 case Type::Boolean:
52 return "ShaderType::kBoolean";
53 case Type::SByte:
54 return "ShaderType::kSignedByte";
55 case Type::UByte:
56 return "ShaderType::kUnsignedByte";
57 case Type::Short:
58 return "ShaderType::kSignedShort";
59 case Type::UShort:
60 return "ShaderType::kUnsignedShort";
61 case Type::Int:
62 return "ShaderType::kSignedInt";
63 case Type::UInt:
64 return "ShaderType::kUnsignedInt";
65 case Type::Int64:
66 return "ShaderType::kSignedInt64";
67 case Type::UInt64:
68 return "ShaderType::kUnsignedInt64";
69 case Type::AtomicCounter:
70 return "ShaderType::kAtomicCounter";
71 case Type::Half:
72 return "ShaderType::kHalfFloat";
73 case Type::Float:
74 return "ShaderType::kFloat";
75 case Type::Double:
76 return "ShaderType::kDouble";
77 case Type::Struct:
78 return "ShaderType::kStruct";
79 case Type::Image:
80 return "ShaderType::kImage";
81 case Type::SampledImage:
82 return "ShaderType::kSampledImage";
83 case Type::Sampler:
84 return "ShaderType::kSampler";
85 default:
86 return "ShaderType::kUnknown";
87 }
89 }
90
92 spirv_cross::SPIRType::BaseType type) {
93 switch (type) {
94 case spirv_cross::SPIRType::Void:
96 case spirv_cross::SPIRType::Float:
98 case spirv_cross::SPIRType::Unknown:
99 case spirv_cross::SPIRType::Boolean:
100 case spirv_cross::SPIRType::SByte:
101 case spirv_cross::SPIRType::UByte:
102 case spirv_cross::SPIRType::Short:
103 case spirv_cross::SPIRType::UShort:
104 case spirv_cross::SPIRType::Int:
105 case spirv_cross::SPIRType::UInt:
106 case spirv_cross::SPIRType::Int64:
107 case spirv_cross::SPIRType::UInt64:
108 case spirv_cross::SPIRType::AtomicCounter:
109 case spirv_cross::SPIRType::Half:
110 case spirv_cross::SPIRType::Double:
111 case spirv_cross::SPIRType::Struct:
112 case spirv_cross::SPIRType::Image:
113 case spirv_cross::SPIRType::SampledImage:
114 case spirv_cross::SPIRType::Sampler:
115 case spirv_cross::SPIRType::AccelerationStructure:
116 case spirv_cross::SPIRType::RayQuery:
117 case spirv_cross::SPIRType::ControlPointArray:
118 case spirv_cross::SPIRType::Interpolant:
119 case spirv_cross::SPIRType::Char:
120 default:
122 }
124 }
125
126 StructMember(std::string p_type,
127 spirv_cross::SPIRType::BaseType p_base_type,
128 std::string p_name,
129 size_t p_offset,
130 size_t p_size,
131 size_t p_byte_length,
132 std::optional<size_t> p_array_elements,
133 size_t p_element_padding,
134 UnderlyingType p_underlying_type = UnderlyingType::kOther)
135 : type(std::move(p_type)),
136 base_type(p_base_type),
137 name(std::move(p_name)),
138 offset(p_offset),
139 size(p_size),
140 byte_length(p_byte_length),
141 array_elements(p_array_elements),
142 element_padding(p_element_padding),
144};
145
147 public:
154
156 const std::shared_ptr<const spirv_cross::ParsedIR>& ir,
157 const std::shared_ptr<fml::Mapping>& shader_data,
159
161
162 bool IsValid() const;
163
164 std::shared_ptr<fml::Mapping> GetReflectionJSON() const;
165
166 std::shared_ptr<fml::Mapping> GetReflectionHeader() const;
167
168 std::shared_ptr<fml::Mapping> GetReflectionCC() const;
169
170 std::shared_ptr<RuntimeStageData::Shader> GetRuntimeStageShaderData() const;
171
172 std::shared_ptr<ShaderBundleData> GetShaderBundleData() const;
173
174 private:
175 struct StructDefinition {
176 std::string name;
177 size_t byte_length = 0u;
178 std::vector<StructMember> members;
179 };
180
181 struct BindPrototypeArgument {
182 std::string type_name;
183 std::string argument_name;
184 };
185
186 struct BindPrototype {
187 std::string name;
188 std::string return_type;
189 std::string docstring;
190 std::string descriptor_type = "";
191 std::vector<BindPrototypeArgument> args;
192 };
193
194 const Options options_;
195 const std::shared_ptr<const spirv_cross::ParsedIR> ir_;
196 const std::shared_ptr<fml::Mapping> shader_data_;
197 const CompilerBackend compiler_;
198 std::unique_ptr<const nlohmann::json> template_arguments_;
199 std::shared_ptr<fml::Mapping> reflection_header_;
200 std::shared_ptr<fml::Mapping> reflection_cc_;
201 std::shared_ptr<RuntimeStageData::Shader> runtime_stage_shader_;
202 std::shared_ptr<ShaderBundleData> shader_bundle_data_;
203 bool is_valid_ = false;
204
205 std::optional<nlohmann::json> GenerateTemplateArguments() const;
206
207 std::shared_ptr<fml::Mapping> GenerateReflectionHeader() const;
208
209 std::shared_ptr<fml::Mapping> GenerateReflectionCC() const;
210
211 std::shared_ptr<RuntimeStageData::Shader> GenerateRuntimeStageData() const;
212
213 std::shared_ptr<ShaderBundleData> GenerateShaderBundleData() const;
214
215 std::shared_ptr<fml::Mapping> InflateTemplate(std::string_view tmpl) const;
216
217 std::optional<nlohmann::json::object_t> ReflectResource(
218 const spirv_cross::Resource& resource,
219 std::optional<size_t> offset) const;
220
221 std::optional<nlohmann::json::array_t> ReflectResources(
222 const spirv_cross::SmallVector<spirv_cross::Resource>& resources,
223 bool compute_offsets = false) const;
224
225 std::vector<size_t> ComputeOffsets(
226 const spirv_cross::SmallVector<spirv_cross::Resource>& resources) const;
227
228 std::optional<size_t> GetOffset(spirv_cross::ID id,
229 const std::vector<size_t>& offsets) const;
230
231 std::optional<nlohmann::json::object_t> ReflectType(
232 const spirv_cross::TypeID& type_id) const;
233
234 nlohmann::json::object_t EmitStructDefinition(
235 std::optional<Reflector::StructDefinition> struc) const;
236
237 std::optional<StructDefinition> ReflectStructDefinition(
238 const spirv_cross::TypeID& type_id) const;
239
240 std::vector<BindPrototype> ReflectBindPrototypes(
241 const spirv_cross::ShaderResources& resources,
242 spv::ExecutionModel execution_model) const;
243
244 nlohmann::json::array_t EmitBindPrototypes(
245 const spirv_cross::ShaderResources& resources,
246 spv::ExecutionModel execution_model) const;
247
248 std::optional<StructDefinition> ReflectPerVertexStructDefinition(
249 const spirv_cross::SmallVector<spirv_cross::Resource>& stage_inputs)
250 const;
251
252 std::optional<std::string> GetMemberNameAtIndexIfExists(
253 const spirv_cross::SPIRType& parent_type,
254 size_t index) const;
255
256 std::string GetMemberNameAtIndex(const spirv_cross::SPIRType& parent_type,
257 size_t index,
258 std::string suffix = "") const;
259
260 std::vector<StructMember> ReadStructMembers(
261 const spirv_cross::TypeID& type_id) const;
262
263 std::optional<uint32_t> GetArrayElements(
264 const spirv_cross::SPIRType& type) const;
265
266 template <uint32_t Size>
267 uint32_t GetArrayStride(const spirv_cross::SPIRType& struct_type,
268 const spirv_cross::SPIRType& member_type,
269 uint32_t index) const {
270 auto element_count = GetArrayElements(member_type).value_or(1);
271 if (element_count <= 1) {
272 return Size;
273 }
274 return compiler_->type_struct_member_array_stride(struct_type, index);
275 };
276
277 Reflector(const Reflector&) = delete;
278
279 Reflector& operator=(const Reflector&) = delete;
280};
281
282} // namespace compiler
283} // namespace impeller
284
285#endif // FLUTTER_IMPELLER_COMPILER_REFLECTOR_H_
const char * options
Reflector(Options options, const std::shared_ptr< const spirv_cross::ParsedIR > &ir, const std::shared_ptr< fml::Mapping > &shader_data, const CompilerBackend &compiler)
Definition reflector.cc:62
std::shared_ptr< fml::Mapping > GetReflectionJSON() const
Definition reflector.cc:108
std::shared_ptr< fml::Mapping > GetReflectionCC() const
Definition reflector.cc:125
std::shared_ptr< RuntimeStageData::Shader > GetRuntimeStageShaderData() const
Definition reflector.cc:129
std::shared_ptr< ShaderBundleData > GetShaderBundleData() const
Definition reflector.cc:134
std::shared_ptr< fml::Mapping > GetReflectionHeader() const
Definition reflector.cc:121
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
#define FML_UNREACHABLE()
Definition logging.h:109
TSize< Scalar > Size
Definition size.h:137
Definition ref_ptr.h:256
Point offset
static std::string BaseTypeToString(spirv_cross::SPIRType::BaseType type)
Definition reflector.h:46
std::optional< size_t > array_elements
Definition reflector.h:42
StructMember(std::string p_type, spirv_cross::SPIRType::BaseType p_base_type, std::string p_name, size_t p_offset, size_t p_size, size_t p_byte_length, std::optional< size_t > p_array_elements, size_t p_element_padding, UnderlyingType p_underlying_type=UnderlyingType::kOther)
Definition reflector.h:126
static UnderlyingType DetermineUnderlyingType(spirv_cross::SPIRType::BaseType type)
Definition reflector.h:91
spirv_cross::SPIRType::BaseType base_type
Definition reflector.h:37