12 #include "fml/backtrace.h"
14 #include "inja/inja.hpp"
17 #include "impeller/runtime_stage/runtime_stage_flatbuffers.h"
18 #include "runtime_stage_types_flatbuffers.h"
29 FML_DCHECK(data_.find(data->backend) == data_.end());
30 data_[data->backend] = data;
33 static std::optional<fb::Stage>
ToStage(spv::ExecutionModel stage) {
35 case spv::ExecutionModel::ExecutionModelVertex:
36 return fb::Stage::kVertex;
37 case spv::ExecutionModel::ExecutionModelFragment:
38 return fb::Stage::kFragment;
39 case spv::ExecutionModel::ExecutionModelGLCompute:
40 return fb::Stage::kCompute;
47 static std::optional<fb::Stage>
ToJsonStage(spv::ExecutionModel stage) {
49 case spv::ExecutionModel::ExecutionModelVertex:
50 return fb::Stage::kVertex;
51 case spv::ExecutionModel::ExecutionModelFragment:
52 return fb::Stage::kFragment;
53 case spv::ExecutionModel::ExecutionModelGLCompute:
54 return fb::Stage::kCompute;
62 spirv_cross::SPIRType::BaseType type) {
64 case spirv_cross::SPIRType::Boolean:
66 case spirv_cross::SPIRType::SByte:
68 case spirv_cross::SPIRType::UByte:
70 case spirv_cross::SPIRType::Short:
72 case spirv_cross::SPIRType::UShort:
74 case spirv_cross::SPIRType::Int:
76 case spirv_cross::SPIRType::UInt:
78 case spirv_cross::SPIRType::Int64:
80 case spirv_cross::SPIRType::UInt64:
82 case spirv_cross::SPIRType::Half:
84 case spirv_cross::SPIRType::Float:
86 case spirv_cross::SPIRType::Double:
88 case spirv_cross::SPIRType::SampledImage:
90 case spirv_cross::SPIRType::AccelerationStructure:
91 case spirv_cross::SPIRType::AtomicCounter:
92 case spirv_cross::SPIRType::Char:
93 case spirv_cross::SPIRType::ControlPointArray:
94 case spirv_cross::SPIRType::Image:
95 case spirv_cross::SPIRType::Interpolant:
96 case spirv_cross::SPIRType::RayQuery:
97 case spirv_cross::SPIRType::Sampler:
98 case spirv_cross::SPIRType::Struct:
99 case spirv_cross::SPIRType::Unknown:
100 case spirv_cross::SPIRType::Void:
106 spirv_cross::SPIRType::BaseType type) {
108 case spirv_cross::SPIRType::Boolean:
110 case spirv_cross::SPIRType::SByte:
112 case spirv_cross::SPIRType::UByte:
114 case spirv_cross::SPIRType::Short:
116 case spirv_cross::SPIRType::UShort:
118 case spirv_cross::SPIRType::Int:
120 case spirv_cross::SPIRType::UInt:
122 case spirv_cross::SPIRType::Int64:
124 case spirv_cross::SPIRType::UInt64:
126 case spirv_cross::SPIRType::Float:
128 case spirv_cross::SPIRType::Double:
130 case spirv_cross::SPIRType::Unknown:
131 case spirv_cross::SPIRType::Void:
132 case spirv_cross::SPIRType::Half:
133 case spirv_cross::SPIRType::AtomicCounter:
134 case spirv_cross::SPIRType::Struct:
135 case spirv_cross::SPIRType::Image:
136 case spirv_cross::SPIRType::SampledImage:
137 case spirv_cross::SPIRType::Sampler:
138 case spirv_cross::SPIRType::AccelerationStructure:
139 case spirv_cross::SPIRType::RayQuery:
140 case spirv_cross::SPIRType::ControlPointArray:
141 case spirv_cross::SPIRType::Interpolant:
142 case spirv_cross::SPIRType::Char:
149 spirv_cross::SPIRType::BaseType type) {
151 case spirv_cross::SPIRType::Boolean:
153 case spirv_cross::SPIRType::SByte:
155 case spirv_cross::SPIRType::UByte:
157 case spirv_cross::SPIRType::Short:
159 case spirv_cross::SPIRType::UShort:
161 case spirv_cross::SPIRType::Int:
163 case spirv_cross::SPIRType::UInt:
165 case spirv_cross::SPIRType::Int64:
167 case spirv_cross::SPIRType::UInt64:
169 case spirv_cross::SPIRType::Half:
171 case spirv_cross::SPIRType::Float:
173 case spirv_cross::SPIRType::Double:
175 case spirv_cross::SPIRType::SampledImage:
177 case spirv_cross::SPIRType::AccelerationStructure:
178 case spirv_cross::SPIRType::AtomicCounter:
179 case spirv_cross::SPIRType::Char:
180 case spirv_cross::SPIRType::ControlPointArray:
181 case spirv_cross::SPIRType::Image:
182 case spirv_cross::SPIRType::Interpolant:
183 case spirv_cross::SPIRType::RayQuery:
184 case spirv_cross::SPIRType::Sampler:
185 case spirv_cross::SPIRType::Struct:
186 case spirv_cross::SPIRType::Unknown:
187 case spirv_cross::SPIRType::Void:
242 for (
const auto& kvp : data_) {
243 nlohmann::json platform_object;
246 if (!stage.has_value()) {
250 platform_object[
kStageKey] =
static_cast<uint32_t
>(stage.value());
253 if (kvp.second->shader->GetSize() > 0u) {
255 reinterpret_cast<const char*
>(kvp.second->shader->GetMapping()),
256 kvp.second->shader->GetSize());
260 auto& uniforms = platform_object[
kUniformsKey] = nlohmann::json::array_t{};
261 for (
const auto& uniform : kvp.second->uniforms) {
262 nlohmann::json uniform_object;
269 if (!uniform_type.has_value()) {
277 if (uniform.array_elements.has_value()) {
279 uniform.array_elements.value();
283 uniforms.push_back(uniform_object);
289 auto json_string = std::make_shared<std::string>(root.dump(2u));
291 return std::make_shared<fml::NonOwnedMapping>(
292 reinterpret_cast<const uint8_t*
>(json_string->data()),
293 json_string->size(), [json_string](
auto,
auto) {});
299 auto runtime_stages = std::make_unique<fb::RuntimeStagesT>();
301 for (
const auto& kvp : data_) {
302 auto runtime_stage = std::make_unique<fb::RuntimeStageT>();
303 runtime_stage->entrypoint = kvp.second->entrypoint;
304 const auto stage =
ToStage(kvp.second->stage);
305 if (!stage.has_value()) {
309 runtime_stage->stage = stage.value();
310 if (!kvp.second->shader) {
314 if (kvp.second->shader->GetSize() > 0u) {
315 runtime_stage->shader = {
316 kvp.second->shader->GetMapping(),
317 kvp.second->shader->GetMapping() + kvp.second->shader->GetSize()};
319 for (
const auto& uniform : kvp.second->uniforms) {
320 auto desc = std::make_unique<fb::UniformDescriptionT>();
322 desc->name = uniform.name;
323 if (desc->name.empty()) {
327 desc->location = uniform.location;
328 desc->rows = uniform.rows;
329 desc->columns = uniform.columns;
331 if (!uniform_type.has_value()) {
335 desc->type = uniform_type.value();
336 desc->bit_width = uniform.bit_width;
337 if (uniform.array_elements.has_value()) {
338 desc->array_elements = uniform.array_elements.value();
341 runtime_stage->uniforms.emplace_back(std::move(desc));
344 for (
const auto& input : kvp.second->inputs) {
345 auto desc = std::make_unique<fb::StageInputT>();
347 desc->name = input.name;
349 if (desc->name.empty()) {
353 desc->location = input.location;
354 desc->set = input.set;
355 desc->binding = input.binding;
357 if (!input_type.has_value()) {
361 desc->type = input_type.value();
362 desc->bit_width = input.bit_width;
363 desc->vec_size = input.vec_size;
364 desc->columns = input.columns;
365 desc->offset = input.offset;
367 runtime_stage->inputs.emplace_back(std::move(desc));
371 runtime_stages->sksl = std::move(runtime_stage);
374 runtime_stages->metal = std::move(runtime_stage);
377 runtime_stages->opengles = std::move(runtime_stage);
380 runtime_stages->vulkan = std::move(runtime_stage);
384 return runtime_stages;
389 if (!runtime_stages) {
393 auto builder = std::make_shared<flatbuffers::FlatBufferBuilder>();
394 builder->Finish(fb::RuntimeStages::Pack(*builder.get(), runtime_stages.get()),
395 fb::RuntimeStagesIdentifier());
396 return std::make_shared<fml::NonOwnedMapping>(builder->GetBufferPointer(),
398 [builder](
auto,
auto) {});