Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
shader_bundle_data.cc
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
6
7#include <optional>
8
9#include "impeller/shader_bundle/shader_bundle_flatbuffers.h"
10
12
13namespace impeller {
14namespace compiler {
15
17 spv::ExecutionModel stage,
18 TargetPlatform target_platform)
19 : entrypoint_(std::move(entrypoint)),
20 stage_(stage),
21 target_platform_(target_platform) {}
22
24
26 uniform_structs_.emplace_back(std::move(uniform_struct));
27}
28
30 uniform_textures_.emplace_back(std::move(uniform_texture));
31}
32
34 inputs_.emplace_back(std::move(input));
35}
36
37void ShaderBundleData::SetShaderData(std::shared_ptr<fml::Mapping> shader) {
38 shader_ = std::move(shader);
39}
40
41static std::optional<fb::shaderbundle::ShaderStage> ToStage(
42 spv::ExecutionModel stage) {
43 switch (stage) {
44 case spv::ExecutionModel::ExecutionModelVertex:
45 return fb::shaderbundle::ShaderStage::kVertex;
46 case spv::ExecutionModel::ExecutionModelFragment:
47 return fb::shaderbundle::ShaderStage::kFragment;
48 case spv::ExecutionModel::ExecutionModelGLCompute:
49 return fb::shaderbundle::ShaderStage::kCompute;
50 default:
51 return std::nullopt;
52 }
54}
55
56static std::optional<fb::shaderbundle::UniformDataType> ToUniformType(
57 spirv_cross::SPIRType::BaseType type) {
58 switch (type) {
59 case spirv_cross::SPIRType::Boolean:
60 return fb::shaderbundle::UniformDataType::kBoolean;
61 case spirv_cross::SPIRType::SByte:
62 return fb::shaderbundle::UniformDataType::kSignedByte;
63 case spirv_cross::SPIRType::UByte:
64 return fb::shaderbundle::UniformDataType::kUnsignedByte;
65 case spirv_cross::SPIRType::Short:
66 return fb::shaderbundle::UniformDataType::kSignedShort;
67 case spirv_cross::SPIRType::UShort:
68 return fb::shaderbundle::UniformDataType::kUnsignedShort;
69 case spirv_cross::SPIRType::Int:
70 return fb::shaderbundle::UniformDataType::kSignedInt;
71 case spirv_cross::SPIRType::UInt:
72 return fb::shaderbundle::UniformDataType::kUnsignedInt;
73 case spirv_cross::SPIRType::Int64:
74 return fb::shaderbundle::UniformDataType::kSignedInt64;
75 case spirv_cross::SPIRType::UInt64:
76 return fb::shaderbundle::UniformDataType::kUnsignedInt64;
77 case spirv_cross::SPIRType::Half:
78 return fb::shaderbundle::UniformDataType::kHalfFloat;
79 case spirv_cross::SPIRType::Float:
80 return fb::shaderbundle::UniformDataType::kFloat;
81 case spirv_cross::SPIRType::Double:
82 return fb::shaderbundle::UniformDataType::kDouble;
83 case spirv_cross::SPIRType::SampledImage:
84 return fb::shaderbundle::UniformDataType::kSampledImage;
85 case spirv_cross::SPIRType::AccelerationStructure:
86 case spirv_cross::SPIRType::AtomicCounter:
87 case spirv_cross::SPIRType::Char:
88 case spirv_cross::SPIRType::ControlPointArray:
89 case spirv_cross::SPIRType::Image:
90 case spirv_cross::SPIRType::Interpolant:
91 case spirv_cross::SPIRType::RayQuery:
92 case spirv_cross::SPIRType::Sampler:
93 case spirv_cross::SPIRType::Struct:
94 case spirv_cross::SPIRType::Unknown:
95 case spirv_cross::SPIRType::Void:
96 return std::nullopt;
97 }
99}
100static std::optional<fb::shaderbundle::InputDataType> ToInputType(
101 spirv_cross::SPIRType::BaseType type) {
102 switch (type) {
103 case spirv_cross::SPIRType::Boolean:
104 return fb::shaderbundle::InputDataType::kBoolean;
105 case spirv_cross::SPIRType::SByte:
106 return fb::shaderbundle::InputDataType::kSignedByte;
107 case spirv_cross::SPIRType::UByte:
108 return fb::shaderbundle::InputDataType::kUnsignedByte;
109 case spirv_cross::SPIRType::Short:
110 return fb::shaderbundle::InputDataType::kSignedShort;
111 case spirv_cross::SPIRType::UShort:
112 return fb::shaderbundle::InputDataType::kUnsignedShort;
113 case spirv_cross::SPIRType::Int:
114 return fb::shaderbundle::InputDataType::kSignedInt;
115 case spirv_cross::SPIRType::UInt:
116 return fb::shaderbundle::InputDataType::kUnsignedInt;
117 case spirv_cross::SPIRType::Int64:
118 return fb::shaderbundle::InputDataType::kSignedInt64;
119 case spirv_cross::SPIRType::UInt64:
120 return fb::shaderbundle::InputDataType::kUnsignedInt64;
121 case spirv_cross::SPIRType::Float:
122 return fb::shaderbundle::InputDataType::kFloat;
123 case spirv_cross::SPIRType::Double:
124 return fb::shaderbundle::InputDataType::kDouble;
125 case spirv_cross::SPIRType::Unknown:
126 case spirv_cross::SPIRType::Void:
127 case spirv_cross::SPIRType::Half:
128 case spirv_cross::SPIRType::AtomicCounter:
129 case spirv_cross::SPIRType::Struct:
130 case spirv_cross::SPIRType::Image:
131 case spirv_cross::SPIRType::SampledImage:
132 case spirv_cross::SPIRType::Sampler:
133 case spirv_cross::SPIRType::AccelerationStructure:
134 case spirv_cross::SPIRType::RayQuery:
135 case spirv_cross::SPIRType::ControlPointArray:
136 case spirv_cross::SPIRType::Interpolant:
137 case spirv_cross::SPIRType::Char:
138 return std::nullopt;
139 }
141}
142
143std::unique_ptr<fb::shaderbundle::BackendShaderT>
145 auto shader_bundle = std::make_unique<fb::shaderbundle::BackendShaderT>();
146
147 // The high level object API is used here for writing to the buffer. This is
148 // just a convenience.
149 shader_bundle->entrypoint = entrypoint_;
150 const auto stage = ToStage(stage_);
151 if (!stage.has_value()) {
152 VALIDATION_LOG << "Invalid shader bundle.";
153 return nullptr;
154 }
155 shader_bundle->stage = stage.value();
156 // This field is ignored, so just set it to anything.
157 if (!shader_) {
158 VALIDATION_LOG << "No shader specified for shader bundle.";
159 return nullptr;
160 }
161 if (shader_->GetSize() > 0u) {
162 shader_bundle->shader = {shader_->GetMapping(),
163 shader_->GetMapping() + shader_->GetSize()};
164 }
165 for (const auto& uniform : uniform_structs_) {
166 auto desc = std::make_unique<fb::shaderbundle::ShaderUniformStructT>();
167
168 desc->name = uniform.name;
169 if (desc->name.empty()) {
170 VALIDATION_LOG << "Uniform name cannot be empty.";
171 return nullptr;
172 }
173 desc->ext_res_0 = uniform.ext_res_0;
174 desc->set = uniform.set;
175 desc->binding = uniform.binding;
176 desc->size_in_bytes = uniform.size_in_bytes;
177
178 for (const auto& field : uniform.fields) {
179 auto field_desc =
180 std::make_unique<fb::shaderbundle::ShaderUniformStructFieldT>();
181 field_desc->name = field.name;
182 auto type = ToUniformType(field.type);
183 if (!type.has_value()) {
184 VALIDATION_LOG << " Invalid shader type " << field.type << ".";
185 return nullptr;
186 }
187 field_desc->type = type.value();
188 field_desc->offset_in_bytes = field.offset_in_bytes;
189 field_desc->element_size_in_bytes = field.element_size_in_bytes;
190 field_desc->total_size_in_bytes = field.total_size_in_bytes;
191 field_desc->array_elements = field.array_elements.value_or(0);
192 desc->fields.push_back(std::move(field_desc));
193 }
194
195 shader_bundle->uniform_structs.emplace_back(std::move(desc));
196 }
197
198 for (const auto& texture : uniform_textures_) {
199 auto desc = std::make_unique<fb::shaderbundle::ShaderUniformTextureT>();
200 desc->name = texture.name;
201 if (desc->name.empty()) {
202 VALIDATION_LOG << "Uniform name cannot be empty.";
203 return nullptr;
204 }
205 desc->ext_res_0 = texture.ext_res_0;
206 desc->set = texture.set;
207 desc->binding = texture.binding;
208 shader_bundle->uniform_textures.emplace_back(std::move(desc));
209 }
210
211 for (const auto& input : inputs_) {
212 auto desc = std::make_unique<fb::shaderbundle::ShaderInputT>();
213
214 desc->name = input.name;
215
216 if (desc->name.empty()) {
217 VALIDATION_LOG << "Stage input name cannot be empty.";
218 return nullptr;
219 }
220 desc->location = input.location;
221 desc->set = input.set;
222 desc->binding = input.binding;
223 auto input_type = ToInputType(input.type);
224 if (!input_type.has_value()) {
225 VALIDATION_LOG << "Invalid uniform type for runtime stage.";
226 return nullptr;
227 }
228 desc->type = input_type.value();
229 desc->bit_width = input.bit_width;
230 desc->vec_size = input.vec_size;
231 desc->columns = input.columns;
232 desc->offset = input.offset;
233
234 shader_bundle->inputs.emplace_back(std::move(desc));
235 }
236
237 return shader_bundle;
238}
239
240} // namespace compiler
241} // namespace impeller
void AddInputDescription(InputDescription input)
ShaderBundleData(std::string entrypoint, spv::ExecutionModel stage, TargetPlatform target_platform)
std::unique_ptr< fb::shaderbundle::BackendShaderT > CreateFlatbuffer() const
void AddUniformStruct(ShaderUniformStruct uniform_struct)
void SetShaderData(std::shared_ptr< fml::Mapping > shader)
void AddUniformTexture(ShaderUniformTexture uniform_texture)
#define FML_UNREACHABLE()
Definition logging.h:109
FlTexture * texture
static std::optional< fb::InputDataType > ToInputType(spirv_cross::SPIRType::BaseType type)
static std::optional< fb::UniformDataType > ToUniformType(spirv_cross::SPIRType::BaseType type)
static std::optional< fb::Stage > ToStage(spv::ExecutionModel stage)
Definition ref_ptr.h:256
#define VALIDATION_LOG
Definition validation.h:73