10 #include "inja/inja.hpp"
13 #include "impeller/runtime_stage/runtime_stage_flatbuffers.h"
19 spv::ExecutionModel stage,
21 : entrypoint_(
std::move(entrypoint)),
23 target_platform_(target_platform) {}
28 uniforms_.emplace_back(std::move(uniform));
32 shader_ = std::move(shader);
36 sksl_ = std::move(sksl);
39 static std::optional<fb::Stage>
ToStage(spv::ExecutionModel stage) {
41 case spv::ExecutionModel::ExecutionModelVertex:
42 return fb::Stage::kVertex;
43 case spv::ExecutionModel::ExecutionModelFragment:
44 return fb::Stage::kFragment;
45 case spv::ExecutionModel::ExecutionModelGLCompute:
46 return fb::Stage::kCompute;
47 case spv::ExecutionModel::ExecutionModelTessellationControl:
48 return fb::Stage::kTessellationControl;
49 case spv::ExecutionModel::ExecutionModelTessellationEvaluation:
50 return fb::Stage::kTessellationEvaluation;
57 static std::optional<uint32_t>
ToJsonStage(spv::ExecutionModel stage) {
59 case spv::ExecutionModel::ExecutionModelVertex:
61 case spv::ExecutionModel::ExecutionModelFragment:
63 case spv::ExecutionModel::ExecutionModelGLCompute:
65 case spv::ExecutionModel::ExecutionModelTessellationControl:
67 case spv::ExecutionModel::ExecutionModelTessellationEvaluation:
86 return fb::TargetPlatform::kSkSL;
88 return fb::TargetPlatform::kMetal;
90 return fb::TargetPlatform::kOpenGLES;
92 return fb::TargetPlatform::kVulkan;
107 return static_cast<uint32_t
>(fb::TargetPlatform::kSkSL);
109 return static_cast<uint32_t
>(fb::TargetPlatform::kMetal);
111 return static_cast<uint32_t
>(fb::TargetPlatform::kOpenGLES);
113 return static_cast<uint32_t
>(fb::TargetPlatform::kVulkan);
118 static std::optional<fb::UniformDataType>
ToType(
119 spirv_cross::SPIRType::BaseType type) {
121 case spirv_cross::SPIRType::Boolean:
123 case spirv_cross::SPIRType::SByte:
125 case spirv_cross::SPIRType::UByte:
127 case spirv_cross::SPIRType::Short:
129 case spirv_cross::SPIRType::UShort:
131 case spirv_cross::SPIRType::Int:
133 case spirv_cross::SPIRType::UInt:
135 case spirv_cross::SPIRType::Int64:
137 case spirv_cross::SPIRType::UInt64:
139 case spirv_cross::SPIRType::Half:
141 case spirv_cross::SPIRType::Float:
143 case spirv_cross::SPIRType::Double:
145 case spirv_cross::SPIRType::SampledImage:
147 case spirv_cross::SPIRType::AccelerationStructure:
148 case spirv_cross::SPIRType::AtomicCounter:
149 case spirv_cross::SPIRType::Char:
150 case spirv_cross::SPIRType::ControlPointArray:
151 case spirv_cross::SPIRType::Image:
152 case spirv_cross::SPIRType::Interpolant:
153 case spirv_cross::SPIRType::RayQuery:
154 case spirv_cross::SPIRType::Sampler:
155 case spirv_cross::SPIRType::Struct:
156 case spirv_cross::SPIRType::Unknown:
157 case spirv_cross::SPIRType::Void:
164 spirv_cross::SPIRType::BaseType type) {
166 case spirv_cross::SPIRType::Boolean:
168 case spirv_cross::SPIRType::SByte:
170 case spirv_cross::SPIRType::UByte:
172 case spirv_cross::SPIRType::Short:
174 case spirv_cross::SPIRType::UShort:
176 case spirv_cross::SPIRType::Int:
178 case spirv_cross::SPIRType::UInt:
180 case spirv_cross::SPIRType::Int64:
182 case spirv_cross::SPIRType::UInt64:
184 case spirv_cross::SPIRType::Half:
186 case spirv_cross::SPIRType::Float:
188 case spirv_cross::SPIRType::Double:
190 case spirv_cross::SPIRType::SampledImage:
192 case spirv_cross::SPIRType::AccelerationStructure:
193 case spirv_cross::SPIRType::AtomicCounter:
194 case spirv_cross::SPIRType::Char:
195 case spirv_cross::SPIRType::ControlPointArray:
196 case spirv_cross::SPIRType::Image:
197 case spirv_cross::SPIRType::Interpolant:
198 case spirv_cross::SPIRType::RayQuery:
199 case spirv_cross::SPIRType::Sampler:
200 case spirv_cross::SPIRType::Struct:
201 case spirv_cross::SPIRType::Unknown:
202 case spirv_cross::SPIRType::Void:
244 if (!stage.has_value()) {
251 if (!target_platform.has_value()) {
257 if (shader_->GetSize() > 0u) {
258 std::string shader(
reinterpret_cast<const char*
>(shader_->GetMapping()),
263 auto& uniforms = root[
kUniformsKey] = nlohmann::json::array_t{};
264 for (
const auto& uniform : uniforms_) {
265 nlohmann::json uniform_object;
272 if (!uniform_type.has_value()) {
280 if (uniform.array_elements.has_value()) {
285 uniforms.push_back(uniform_object);
288 auto json_string = std::make_shared<std::string>(root.dump(2u));
290 return std::make_shared<fml::NonOwnedMapping>(
291 reinterpret_cast<const uint8_t*
>(json_string->data()),
292 json_string->size(), [json_string](
auto,
auto) {});
298 fb::RuntimeStageT runtime_stage;
299 runtime_stage.entrypoint = entrypoint_;
300 const auto stage =
ToStage(stage_);
301 if (!stage.has_value()) {
305 runtime_stage.stage = stage.value();
307 if (!target_platform.has_value()) {
311 runtime_stage.target_platform = target_platform.value();
316 if (shader_->GetSize() > 0u) {
317 runtime_stage.shader = {shader_->GetMapping(),
318 shader_->GetMapping() + shader_->GetSize()};
321 if (sksl_->GetSize() > 0u) {
322 runtime_stage.sksl = {sksl_->GetMapping(),
323 sksl_->GetMapping() + sksl_->GetSize()};
325 for (
const auto& uniform : uniforms_) {
326 auto desc = std::make_unique<fb::UniformDescriptionT>();
328 desc->name = uniform.name;
329 if (desc->name.empty()) {
333 desc->location = uniform.location;
334 desc->rows = uniform.rows;
335 desc->columns = uniform.columns;
336 auto uniform_type =
ToType(uniform.type);
337 if (!uniform_type.has_value()) {
341 desc->type = uniform_type.value();
342 desc->bit_width = uniform.bit_width;
343 if (uniform.array_elements.has_value()) {
344 desc->array_elements = uniform.array_elements.value();
347 runtime_stage.uniforms.emplace_back(std::move(desc));
349 auto builder = std::make_shared<flatbuffers::FlatBufferBuilder>();
350 builder->Finish(fb::RuntimeStage::Pack(*builder.get(), &runtime_stage),
351 fb::RuntimeStageIdentifier());
352 return std::make_shared<fml::NonOwnedMapping>(builder->GetBufferPointer(),
354 [builder](
auto,
auto) {});