blob: df71ece7504f3c00d5381aa3c3301eb02f27af69 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "impeller/renderer/backend/vulkan/shader_library_vk.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/trace_event.h"
#include "impeller/blobcat/blob_library.h"
#include "impeller/renderer/backend/vulkan/context_vk.h"
#include "impeller/renderer/backend/vulkan/shader_function_vk.h"
namespace impeller {
static ShaderStage ToShaderStage(BlobShaderType type) {
switch (type) {
case BlobShaderType::kVertex:
return ShaderStage::kVertex;
case BlobShaderType::kFragment:
return ShaderStage::kFragment;
case BlobShaderType::kCompute:
return ShaderStage::kCompute;
}
FML_UNREACHABLE();
}
static std::string VKShaderNameToShaderKeyName(const std::string& name,
ShaderStage stage) {
std::stringstream stream;
stream << name;
switch (stage) {
case ShaderStage::kUnknown:
stream << "_unknown_";
break;
case ShaderStage::kVertex:
stream << "_vertex_";
break;
case ShaderStage::kFragment:
stream << "_fragment_";
break;
case ShaderStage::kTessellationControl:
stream << "_tessellation_control_";
break;
case ShaderStage::kTessellationEvaluation:
stream << "_tessellation_evaluation_";
break;
case ShaderStage::kCompute:
stream << "_compute_";
break;
}
stream << "main";
return stream.str();
}
ShaderLibraryVK::ShaderLibraryVK(
const vk::Device& device,
const std::vector<std::shared_ptr<fml::Mapping>>& shader_libraries_data) {
TRACE_EVENT0("impeller", "ShaderLibraryCreate");
ShaderFunctionMap functions;
bool success = true;
auto iterator = [&success, &device, &functions, library_id = library_id_](
auto type, //
const auto& name, //
const auto& mapping //
) -> bool {
vk::ShaderModuleCreateInfo shader_module_info;
shader_module_info.setPCode(
reinterpret_cast<const uint32_t*>(mapping->GetMapping()));
shader_module_info.setCodeSize(mapping->GetSize());
auto module = device.createShaderModuleUnique(shader_module_info);
if (module.result != vk::Result::eSuccess) {
VALIDATION_LOG << "Could not create shader module: "
<< vk::to_string(module.result);
success = false;
return false;
}
const auto stage = ToShaderStage(type);
const auto key_name = VKShaderNameToShaderKeyName(name, stage);
vk::UniqueShaderModule shader_module = std::move(module.value);
ContextVK::SetDebugName(device, *shader_module,
"shader_module_" + key_name);
functions[ShaderKey{key_name, stage}] = std::shared_ptr<ShaderFunctionVK>(
new ShaderFunctionVK(library_id, //
key_name, //
stage, //
std::move(shader_module) //
));
return true;
};
for (const auto& library_data : shader_libraries_data) {
auto blob_library = BlobLibrary{library_data};
if (!blob_library.IsValid()) {
VALIDATION_LOG << "Could not construct shader blob library.";
return;
}
blob_library.IterateAllBlobs(iterator);
}
if (!success) {
return;
}
functions_ = std::move(functions);
is_valid_ = true;
}
ShaderLibraryVK::~ShaderLibraryVK() = default;
bool ShaderLibraryVK::IsValid() const {
return is_valid_;
}
std::shared_ptr<const ShaderFunction> ShaderLibraryVK::GetFunction(
std::string_view name,
ShaderStage stage) {
ReaderLock lock(functions_mutex_);
const auto key = ShaderKey{{name.data(), name.size()}, stage};
auto found = functions_.find(key);
if (found != functions_.end()) {
return found->second;
}
return nullptr;
}
// |ShaderLibrary|
void ShaderLibraryVK::UnregisterFunction(std::string name, ShaderStage stage) {
ReaderLock lock(functions_mutex_);
const auto key = ShaderKey{name, stage};
auto found = functions_.find(key);
if (found != functions_.end()) {
VALIDATION_LOG << "Library function named " << name
<< " was not found, so it couldn't be unregistered.";
return;
}
functions_.erase(found);
return;
}
} // namespace impeller