5 #ifndef FLUTTER_IMPELLER_COMPILER_REFLECTOR_H_
6 #define FLUTTER_IMPELLER_COMPILER_REFLECTOR_H_
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"
47 using Type = spirv_cross::SPIRType::BaseType;
50 return "ShaderType::kVoid";
52 return "ShaderType::kBoolean";
54 return "ShaderType::kSignedByte";
56 return "ShaderType::kUnsignedByte";
58 return "ShaderType::kSignedShort";
60 return "ShaderType::kUnsignedShort";
62 return "ShaderType::kSignedInt";
64 return "ShaderType::kUnsignedInt";
66 return "ShaderType::kSignedInt64";
68 return "ShaderType::kUnsignedInt64";
69 case Type::AtomicCounter:
70 return "ShaderType::kAtomicCounter";
72 return "ShaderType::kHalfFloat";
74 return "ShaderType::kFloat";
76 return "ShaderType::kDouble";
78 return "ShaderType::kStruct";
80 return "ShaderType::kImage";
81 case Type::SampledImage:
82 return "ShaderType::kSampledImage";
84 return "ShaderType::kSampler";
86 return "ShaderType::kUnknown";
92 spirv_cross::SPIRType::BaseType
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:
127 spirv_cross::SPIRType::BaseType p_base_type,
131 size_t p_byte_length,
132 std::optional<size_t> p_array_elements,
133 size_t p_element_padding,
156 const std::shared_ptr<const spirv_cross::ParsedIR>& ir,
157 const std::shared_ptr<fml::Mapping>& shader_data,
175 struct StructDefinition {
177 size_t byte_length = 0u;
178 std::vector<StructMember> members;
181 struct BindPrototypeArgument {
182 std::string type_name;
183 std::string argument_name;
186 struct BindPrototype {
188 std::string return_type;
189 std::string docstring;
190 std::string descriptor_type =
"";
191 std::vector<BindPrototypeArgument> args;
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;
205 std::optional<nlohmann::json> GenerateTemplateArguments()
const;
207 std::shared_ptr<fml::Mapping> GenerateReflectionHeader()
const;
209 std::shared_ptr<fml::Mapping> GenerateReflectionCC()
const;
211 std::shared_ptr<RuntimeStageData::Shader> GenerateRuntimeStageData()
const;
213 std::shared_ptr<ShaderBundleData> GenerateShaderBundleData()
const;
215 std::shared_ptr<fml::Mapping> InflateTemplate(std::string_view tmpl)
const;
217 std::optional<nlohmann::json::object_t> ReflectResource(
218 const spirv_cross::Resource& resource,
219 std::optional<size_t>
offset)
const;
221 std::optional<nlohmann::json::array_t> ReflectResources(
222 const spirv_cross::SmallVector<spirv_cross::Resource>& resources,
223 bool compute_offsets =
false)
const;
225 std::vector<size_t> ComputeOffsets(
226 const spirv_cross::SmallVector<spirv_cross::Resource>& resources)
const;
228 std::optional<size_t> GetOffset(spirv_cross::ID
id,
229 const std::vector<size_t>& offsets)
const;
231 std::optional<nlohmann::json::object_t> ReflectType(
232 const spirv_cross::TypeID& type_id)
const;
234 nlohmann::json::object_t EmitStructDefinition(
235 std::optional<Reflector::StructDefinition> struc)
const;
237 std::optional<StructDefinition> ReflectStructDefinition(
238 const spirv_cross::TypeID& type_id)
const;
240 std::vector<BindPrototype> ReflectBindPrototypes(
241 const spirv_cross::ShaderResources& resources,
242 spv::ExecutionModel execution_model)
const;
244 nlohmann::json::array_t EmitBindPrototypes(
245 const spirv_cross::ShaderResources& resources,
246 spv::ExecutionModel execution_model)
const;
248 std::optional<StructDefinition> ReflectPerVertexStructDefinition(
249 const spirv_cross::SmallVector<spirv_cross::Resource>& stage_inputs)
252 std::optional<std::string> GetMemberNameAtIndexIfExists(
253 const spirv_cross::SPIRType& parent_type,
256 std::string GetMemberNameAtIndex(
const spirv_cross::SPIRType& parent_type,
258 std::string suffix =
"")
const;
260 std::vector<StructMember> ReadStructMembers(
261 const spirv_cross::TypeID& type_id)
const;
263 std::optional<uint32_t> GetArrayElements(
264 const spirv_cross::SPIRType& type)
const;
266 template <u
int32_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) {
274 return compiler_->type_struct_member_array_stride(struct_type, index);
285 #endif // FLUTTER_IMPELLER_COMPILER_REFLECTOR_H_