Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
shader_library_vk.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 <cstdint>
8
14
15namespace impeller {
16
28
29static std::string VKShaderNameToShaderKeyName(const std::string& name,
30 ShaderStage stage) {
31 std::stringstream stream;
32 stream << name;
33 switch (stage) {
35 stream << "_unknown_";
36 break;
38 stream << "_vertex_";
39 break;
41 stream << "_fragment_";
42 break;
44 stream << "_compute_";
45 break;
46 }
47 stream << "main";
48 return stream.str();
49}
50
51ShaderLibraryVK::ShaderLibraryVK(
52 std::weak_ptr<DeviceHolderVK> device_holder,
53 const std::vector<std::shared_ptr<fml::Mapping>>& shader_libraries_data)
54 : device_holder_(std::move(device_holder)) {
55 TRACE_EVENT0("impeller", "CreateShaderLibrary");
56 bool success = true;
57 auto iterator = [&](auto type, //
58 const auto& name, //
59 const auto& code //
60 ) -> bool {
61 const auto stage = ToShaderStage(type);
62 if (!RegisterFunction(VKShaderNameToShaderKeyName(name, stage), stage,
63 code)) {
64 success = false;
65 return false;
66 }
67 return true;
68 };
69 for (const auto& library_data : shader_libraries_data) {
70 auto blob_library = ShaderArchive::Create(library_data);
71 if (!blob_library.ok()) {
72 VALIDATION_LOG << "Could not construct shader blob library: "
73 << blob_library.status().ToString();
74 return;
75 }
76 blob_library->IterateAllShaders(iterator);
77 }
78
79 if (!success) {
80 VALIDATION_LOG << "Could not create shader modules for all shader blobs.";
81 return;
82 }
83 is_valid_ = true;
84}
85
86ShaderLibraryVK::~ShaderLibraryVK() = default;
87
88bool ShaderLibraryVK::IsValid() const {
89 return is_valid_;
90}
91
92// |ShaderLibrary|
93std::shared_ptr<const ShaderFunction> ShaderLibraryVK::GetFunction(
94 std::string_view name,
95 ShaderStage stage) {
96 ReaderLock lock(functions_mutex_);
97
98 const auto key = ShaderKey{{name.data(), name.size()}, stage};
99 auto found = functions_.find(key);
100 if (found != functions_.end()) {
101 return found->second;
102 }
103 return nullptr;
104}
105
106// |ShaderLibrary|
107void ShaderLibraryVK::RegisterFunction(std::string name,
108 ShaderStage stage,
109 std::shared_ptr<fml::Mapping> code,
110 RegistrationCallback callback) {
111 const auto result = RegisterFunction(name, stage, code);
112 if (callback) {
113 callback(result);
114 }
115}
116
117static bool IsMappingSPIRV(const fml::Mapping& mapping) {
118 // https://registry.khronos.org/SPIR-V/specs/1.0/SPIRV.html#Magic
119 const uint32_t kSPIRVMagic = 0x07230203;
120 if (mapping.GetSize() < sizeof(kSPIRVMagic)) {
121 return false;
122 }
123 uint32_t magic = 0u;
124 ::memcpy(&magic, mapping.GetMapping(), sizeof(magic));
125 return magic == kSPIRVMagic;
126}
127
128bool ShaderLibraryVK::RegisterFunction(
129 const std::string& name,
130 ShaderStage stage,
131 const std::shared_ptr<fml::Mapping>& code) {
132 if (!code) {
133 return false;
134 }
135
136 if (!IsMappingSPIRV(*code)) {
137 VALIDATION_LOG << "Shader is not valid SPIRV.";
138 return false;
139 }
140
141 vk::ShaderModuleCreateInfo shader_module_info;
142
143 shader_module_info.setPCode(
144 reinterpret_cast<const uint32_t*>(code->GetMapping()));
145 shader_module_info.setCodeSize(code->GetSize());
146
147 auto device_holder = device_holder_.lock();
148 if (!device_holder) {
149 return false;
150 }
151 FML_DCHECK(device_holder->GetDevice());
152 auto module =
153 device_holder->GetDevice().createShaderModuleUnique(shader_module_info);
154
155 if (module.result != vk::Result::eSuccess) {
156 VALIDATION_LOG << "Could not create shader module: "
157 << vk::to_string(module.result);
158 return false;
159 }
160
161 vk::UniqueShaderModule shader_module = std::move(module.value);
162 ContextVK::SetDebugName(device_holder->GetDevice(), *shader_module,
163 "Shader " + name);
164
165 WriterLock lock(functions_mutex_);
166 functions_[ShaderKey{name, stage}] = std::shared_ptr<ShaderFunctionVK>(
167 new ShaderFunctionVK(device_holder_,
168 library_id_, //
169 name, //
170 stage, //
171 std::move(shader_module) //
172 ));
173
174 return true;
175}
176
177// |ShaderLibrary|
178void ShaderLibraryVK::UnregisterFunction(std::string name, ShaderStage stage) {
179 WriterLock lock(functions_mutex_);
180
181 const auto key = ShaderKey{name, stage};
182
183 auto found = functions_.find(key);
184 if (found == functions_.end()) {
185 VALIDATION_LOG << "Library function named " << name
186 << " was not found, so it couldn't be unregistered.";
187 return;
188 }
189
190 functions_.erase(found);
191
192 return;
193}
194
195} // namespace impeller
GLenum type
virtual const uint8_t * GetMapping() const =0
virtual size_t GetSize() const =0
static absl::StatusOr< ShaderArchive > Create(std::shared_ptr< fml::Mapping > payload)
FlutterDesktopBinaryReply callback
#define FML_UNREACHABLE()
Definition logging.h:128
#define FML_DCHECK(condition)
Definition logging.h:122
const char * name
Definition fuchsia.cc:49
constexpr ShaderStage ToShaderStage(RuntimeShaderStage stage)
static bool IsMappingSPIRV(const fml::Mapping &mapping)
static std::string VKShaderNameToShaderKeyName(const std::string &name, ShaderStage stage)
Definition ref_ptr.h:261
#define TRACE_EVENT0(category_group, name)
#define VALIDATION_LOG
Definition validation.h:91