| Flutter Impeller |

runtime_stage.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
5 #include "impeller/runtime_stage/runtime_stage.h"
6
7 #include <array>
8 #include <memory>
9
10 #include "fml/mapping.h"
11 #include "impeller/base/validation.h"
12 #include "impeller/core/runtime_types.h"
13 #include "impeller/core/shader_types.h"
14 #include "impeller/runtime_stage/runtime_stage_flatbuffers.h"
15 #include "runtime_stage_types_flatbuffers.h"
16
17 namespace impeller {
18
19 static RuntimeUniformType ToType(fb::UniformDataType type) {
20 switch (type) {
21 case fb::UniformDataType::kFloat:
22 return RuntimeUniformType::kFloat;
23 case fb::UniformDataType::kSampledImage:
24 return RuntimeUniformType::kSampledImage;
25 case fb::UniformDataType::kStruct:
26 return RuntimeUniformType::kStruct;
27 }
28 FML_UNREACHABLE();
29 }
30
31 static RuntimeShaderStage ToShaderStage(fb::Stage stage) {
32 switch (stage) {
33 case fb::Stage::kVertex:
34 return RuntimeShaderStage::kVertex;
35 case fb::Stage::kFragment:
36 return RuntimeShaderStage::kFragment;
37 case fb::Stage::kCompute:
38 return RuntimeShaderStage::kCompute;
39 }
40 FML_UNREACHABLE();
41 }
42
43 /// The generated name from GLSLang/shaderc for the UBO containing non-opaque
44 /// uniforms specified in the user-written runtime effect shader.
45 ///
46 /// Vulkan does not allow non-opaque uniforms outside of a UBO.
47 const char* RuntimeStage::kVulkanUBOName =
48 "_RESERVED_IDENTIFIER_FIXUP_gl_DefaultUniformBlock";
49
50 std::unique_ptr<RuntimeStage> RuntimeStage::RuntimeStageIfPresent(
51 const fb::RuntimeStage* runtime_stage,
52 const std::shared_ptr<fml::Mapping>& payload) {
53 if (!runtime_stage) {
54 return nullptr;
55 }
56
57 // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
58 return std::unique_ptr<RuntimeStage>(
59 new RuntimeStage(runtime_stage, payload));
60 }
61
62 RuntimeStage::Map RuntimeStage::DecodeRuntimeStages(
63 const std::shared_ptr<fml::Mapping>& payload) {
64 if (payload == nullptr || !payload->GetMapping()) {
65 return {};
66 }
67 if (!fb::RuntimeStagesBufferHasIdentifier(payload->GetMapping())) {
68 return {};
69 }
70
71 auto raw_stages = fb::GetRuntimeStages(payload->GetMapping());
72 return {
73 {RuntimeStageBackend::kSkSL,
74 RuntimeStageIfPresent(raw_stages->sksl(), payload)},
75 {RuntimeStageBackend::kMetal,
76 RuntimeStageIfPresent(raw_stages->metal(), payload)},
77 {RuntimeStageBackend::kOpenGLES,
78 RuntimeStageIfPresent(raw_stages->opengles(), payload)},
79 {RuntimeStageBackend::kOpenGLES3,
80 RuntimeStageIfPresent(raw_stages->opengles3(), payload)},
81 {RuntimeStageBackend::kVulkan,
82 RuntimeStageIfPresent(raw_stages->vulkan(), payload)},
83 };
84 }
85
86 RuntimeStage::RuntimeStage(const fb::RuntimeStage* runtime_stage,
87 const std::shared_ptr<fml::Mapping>& payload)
88 : payload_(payload) {
89 FML_DCHECK(runtime_stage);
90
91 stage_ = ToShaderStage(runtime_stage->stage());
92 entrypoint_ = runtime_stage->entrypoint()->str();
93
94 auto* uniforms = runtime_stage->uniforms();
95
96 // Note: image bindings are screwy and will always have the same offset.
97 // track the binding of the UBO to determine where the image bindings go.
98 // This is only guaranteed to give us the correct bindings if there is a
99 // single sampler2D.
100 std::optional<size_t> ubo_id;
101 if (uniforms) {
102 for (auto i = uniforms->begin(), end = uniforms->end(); i != end; i++) {
103 RuntimeUniformDescription desc;
104 desc.name = i->name()->str();
105 desc.location = i->location();
106 desc.binding = i->binding();
107 desc.type = ToType(i->type());
108 if (desc.type == kStruct) {
109 ubo_id = desc.location;
110 desc.binding = desc.location;
111 }
112 desc.dimensions = RuntimeUniformDimensions{
113 static_cast<size_t>(i->rows()), static_cast<size_t>(i->columns())};
114 desc.bit_width = i->bit_width();
115 desc.array_elements = i->array_elements();
116 if (i->struct_layout()) {
117 for (const auto& byte_type : *i->struct_layout()) {
118 desc.struct_layout.push_back(static_cast<uint8_t>(byte_type));
119 }
120 }
121 desc.struct_float_count = i->struct_float_count();
122 uniforms_.push_back(std::move(desc));
123 }
124 }
125
126 code_mapping_ = std::make_shared<fml::NonOwnedMapping>(
127 runtime_stage->shader()->data(), //
128 runtime_stage->shader()->size(), //
129 [payload = payload_](auto, auto) {} //
130 );
131
132 size_t binding = 64;
133 if (ubo_id.has_value() && ubo_id.value() == binding) {
134 binding++;
135 }
136 for (auto& uniform : uniforms_) {
137 if (uniform.type == kSampledImage) {
138 uniform.binding = binding;
139 binding++;
140 if (ubo_id.has_value() && ubo_id.value() == binding) {
141 binding++;
142 }
143 }
144 }
145
146 for (const auto& uniform : GetUniforms()) {
147 if (uniform.type == kStruct) {
148 descriptor_set_layouts_.push_back(DescriptorSetLayout{
149 static_cast<uint32_t>(uniform.location),
150 DescriptorType::kUniformBuffer,
151 ShaderStage::kFragment,
152 });
153 } else if (uniform.type == kSampledImage) {
154 descriptor_set_layouts_.push_back(DescriptorSetLayout{
155 static_cast<uint32_t>(uniform.binding),
156 DescriptorType::kSampledImage,
157 ShaderStage::kFragment,
158 });
159 }
160 }
161 is_valid_ = true;
162 }
163
164 RuntimeStage::~RuntimeStage() = default;
165 RuntimeStage::RuntimeStage(RuntimeStage&&) = default;
166 RuntimeStage& RuntimeStage::operator=(RuntimeStage&&) = default;
167
168 bool RuntimeStage::IsValid() const {
169 return is_valid_;
170 }
171
172 const std::shared_ptr<fml::Mapping>& RuntimeStage::GetCodeMapping() const {
173 return code_mapping_;
174 }
175
176 const std::vector<RuntimeUniformDescription>& RuntimeStage::GetUniforms()
177 const {
178 return uniforms_;
179 }
180
181 const RuntimeUniformDescription* RuntimeStage::GetUniform(
182 const std::string& name) const {
183 for (const auto& uniform : uniforms_) {
184 if (uniform.name == name) {
185 return &uniform;
186 }
187 }
188 return nullptr;
189 }
190
191 const std::string& RuntimeStage::GetEntrypoint() const {
192 return entrypoint_;
193 }
194
195 RuntimeShaderStage RuntimeStage::GetShaderStage() const {
196 return stage_;
197 }
198
199 bool RuntimeStage::IsDirty() const {
200 return is_dirty_;
201 }
202
203 void RuntimeStage::SetClean() {
204 is_dirty_ = false;
205 }
206
207 const std::vector<DescriptorSetLayout>& RuntimeStage::GetDescriptorSetLayouts()
208 const {
209 return descriptor_set_layouts_;
210 }
211
212 } // namespace impeller
type
GLenum type
Definition: blit_command_gles.cc:151
impeller::RuntimeStage
Definition: runtime_stage.h:20
impeller::RuntimeStage::~RuntimeStage
~RuntimeStage()
impeller::RuntimeStage::GetEntrypoint
const std::string & GetEntrypoint() const
Definition: runtime_stage.cc:191
impeller::RuntimeStage::operator=
RuntimeStage & operator=(RuntimeStage &&)
impeller::RuntimeStage::GetUniforms
const std::vector< RuntimeUniformDescription > & GetUniforms() const
Definition: runtime_stage.cc:176
impeller::RuntimeStage::SetClean
void SetClean()
Definition: runtime_stage.cc:203
impeller::RuntimeStage::IsValid
bool IsValid() const
Definition: runtime_stage.cc:168
impeller::RuntimeStage::GetUniform
const RuntimeUniformDescription * GetUniform(const std::string &name) const
Definition: runtime_stage.cc:181
impeller::RuntimeStage::Map
std::map< RuntimeStageBackend, std::shared_ptr< RuntimeStage > > Map
Definition: runtime_stage.h:24
impeller::RuntimeStage::kVulkanUBOName
static const char * kVulkanUBOName
Definition: runtime_stage.h:22
impeller::RuntimeStage::DecodeRuntimeStages
static Map DecodeRuntimeStages(const std::shared_ptr< fml::Mapping > &payload)
Definition: runtime_stage.cc:62
impeller::RuntimeStage::GetCodeMapping
const std::shared_ptr< fml::Mapping > & GetCodeMapping() const
Definition: runtime_stage.cc:172
impeller::RuntimeStage::IsDirty
bool IsDirty() const
Definition: runtime_stage.cc:199
impeller::RuntimeStage::GetDescriptorSetLayouts
const std::vector< DescriptorSetLayout > & GetDescriptorSetLayouts() const
Definition: runtime_stage.cc:207
impeller::RuntimeStage::GetShaderStage
RuntimeShaderStage GetShaderStage() const
Definition: runtime_stage.cc:195
impeller::RuntimeStage::RuntimeStage
RuntimeStage(const fb::RuntimeStage *runtime_stage, const std::shared_ptr< fml::Mapping > &payload)
Definition: runtime_stage.cc:86
impeller
Definition: allocation.cc:12
impeller::RuntimeShaderStage
RuntimeShaderStage
Definition: runtime_types.h:30
impeller::RuntimeShaderStage::kCompute
@ kCompute
impeller::RuntimeShaderStage::kFragment
@ kFragment
impeller::RuntimeShaderStage::kVertex
@ kVertex
impeller::RuntimeStageBackend::kOpenGLES
@ kOpenGLES
impeller::RuntimeStageBackend::kMetal
@ kMetal
impeller::RuntimeStageBackend::kVulkan
@ kVulkan
impeller::RuntimeStageBackend::kSkSL
@ kSkSL
impeller::RuntimeStageBackend::kOpenGLES3
@ kOpenGLES3
impeller::ToShaderStage
constexpr ShaderStage ToShaderStage(RuntimeShaderStage stage)
Definition: shader_types.h:29
impeller::ShaderStage::kFragment
@ kFragment
impeller::ToType
static RuntimeUniformType ToType(fb::UniformDataType type)
Definition: runtime_stage.cc:19
impeller::DescriptorType::kUniformBuffer
@ kUniformBuffer
impeller::DescriptorType::kSampledImage
@ kSampledImage
impeller::RuntimeUniformType
RuntimeUniformType
Definition: runtime_types.h:24
impeller::kSampledImage
@ kSampledImage
Definition: runtime_types.h:26
impeller::kFloat
@ kFloat
Definition: runtime_types.h:25
impeller::kStruct
@ kStruct
Definition: runtime_types.h:27
runtime_stage.h
runtime_types.h
shader_types.h
impeller::DescriptorSetLayout
Definition: shader_types.h:167
impeller::RuntimeUniformDescription
Definition: runtime_types.h:41
impeller::RuntimeUniformDescription::dimensions
RuntimeUniformDimensions dimensions
Definition: runtime_types.h:47
impeller::RuntimeUniformDescription::location
size_t location
Definition: runtime_types.h:43
impeller::RuntimeUniformDescription::struct_layout
std::vector< uint8_t > struct_layout
Definition: runtime_types.h:50
impeller::RuntimeUniformDescription::name
std::string name
Definition: runtime_types.h:42
impeller::RuntimeUniformDescription::type
RuntimeUniformType type
Definition: runtime_types.h:46
impeller::RuntimeUniformDescription::struct_float_count
size_t struct_float_count
Definition: runtime_types.h:51
impeller::RuntimeUniformDescription::array_elements
std::optional< size_t > array_elements
Definition: runtime_types.h:49
impeller::RuntimeUniformDescription::bit_width
size_t bit_width
Definition: runtime_types.h:48
impeller::RuntimeUniformDescription::binding
size_t binding
Location, but for Vulkan.
Definition: runtime_types.h:45
impeller::RuntimeUniformDimensions
Definition: runtime_types.h:36
validation.h