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