Flutter Engine
The Flutter Engine
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
9#include "flutter/fml/logging.h"
10#include "flutter/fml/trace_event.h"
14
15namespace impeller {
16
18 switch (type) {
25 }
27}
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{library_data};
71 if (!blob_library.IsValid()) {
72 VALIDATION_LOG << "Could not construct shader blob library.";
73 return;
74 }
75 blob_library.IterateAllShaders(iterator);
76 }
77
78 if (!success) {
79 VALIDATION_LOG << "Could not create shader modules for all shader blobs.";
80 return;
81 }
82 is_valid_ = true;
83}
84
85ShaderLibraryVK::~ShaderLibraryVK() = default;
86
87bool ShaderLibraryVK::IsValid() const {
88 return is_valid_;
89}
90
91// |ShaderLibrary|
92std::shared_ptr<const ShaderFunction> ShaderLibraryVK::GetFunction(
93 std::string_view name,
94 ShaderStage stage) {
95 ReaderLock lock(functions_mutex_);
96
97 const auto key = ShaderKey{{name.data(), name.size()}, stage};
98 auto found = functions_.find(key);
99 if (found != functions_.end()) {
100 return found->second;
101 }
102 return nullptr;
103}
104
105// |ShaderLibrary|
106void ShaderLibraryVK::RegisterFunction(std::string name,
107 ShaderStage stage,
108 std::shared_ptr<fml::Mapping> code,
109 RegistrationCallback callback) {
110 const auto result = RegisterFunction(name, stage, code);
111 if (callback) {
113 }
114}
115
116static bool IsMappingSPIRV(const fml::Mapping& mapping) {
117 // https://registry.khronos.org/SPIR-V/specs/1.0/SPIRV.html#Magic
118 const uint32_t kSPIRVMagic = 0x07230203;
119 if (mapping.GetSize() < sizeof(kSPIRVMagic)) {
120 return false;
121 }
122 uint32_t magic = 0u;
123 ::memcpy(&magic, mapping.GetMapping(), sizeof(magic));
124 return magic == kSPIRVMagic;
125}
126
127bool ShaderLibraryVK::RegisterFunction(
128 const std::string& name,
129 ShaderStage stage,
130 const std::shared_ptr<fml::Mapping>& code) {
131 if (!code) {
132 return false;
133 }
134
135 if (!IsMappingSPIRV(*code)) {
136 VALIDATION_LOG << "Shader is not valid SPIRV.";
137 return false;
138 }
139
140 vk::ShaderModuleCreateInfo shader_module_info;
141
142 shader_module_info.setPCode(
143 reinterpret_cast<const uint32_t*>(code->GetMapping()));
144 shader_module_info.setCodeSize(code->GetSize());
145
146 auto device_holder = device_holder_.lock();
147 if (!device_holder) {
148 return false;
149 }
150 FML_DCHECK(device_holder->GetDevice());
151 auto module =
152 device_holder->GetDevice().createShaderModuleUnique(shader_module_info);
153
154 if (module.result != vk::Result::eSuccess) {
155 VALIDATION_LOG << "Could not create shader module: "
156 << vk::to_string(module.result);
157 return false;
158 }
159
160 vk::UniqueShaderModule shader_module = std::move(module.value);
161 ContextVK::SetDebugName(device_holder->GetDevice(), *shader_module,
162 "Shader " + name);
163
164 WriterLock lock(functions_mutex_);
165 functions_[ShaderKey{name, stage}] = std::shared_ptr<ShaderFunctionVK>(
166 new ShaderFunctionVK(device_holder_,
167 library_id_, //
168 name, //
169 stage, //
170 std::move(shader_module) //
171 ));
172
173 return true;
174}
175
176// |ShaderLibrary|
177void ShaderLibraryVK::UnregisterFunction(std::string name, ShaderStage stage) {
178 WriterLock lock(functions_mutex_);
179
180 const auto key = ShaderKey{name, stage};
181
182 auto found = functions_.find(key);
183 if (found == functions_.end()) {
184 VALIDATION_LOG << "Library function named " << name
185 << " was not found, so it couldn't be unregistered.";
186 return;
187 }
188
189 functions_.erase(found);
190
191 return;
192}
193
194} // namespace impeller
GLenum type
virtual const uint8_t * GetMapping() const =0
virtual size_t GetSize() const =0
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
GAsyncResult * result
#define FML_UNREACHABLE()
Definition: logging.h:109
#define FML_DCHECK(condition)
Definition: logging.h:103
FunctionPtr GetFunction(const Library &lib, const char *name)
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
constexpr ShaderStage ToShaderStage(RuntimeShaderStage stage)
Definition: shader_types.h:29
static bool IsMappingSPIRV(const fml::Mapping &mapping)
static std::string VKShaderNameToShaderKeyName(const std::string &name, ShaderStage stage)
Definition: ref_ptr.h:256
static SkString to_string(int n)
Definition: nanobench.cpp:119
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:131
#define VALIDATION_LOG
Definition: validation.h:73