blob: dfb3cbc50357edcd8ddba0b5dae527630e9f671f [file] [log] [blame]
// Copyright 2018 The Fuchsia 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 "src/ui/lib/escher/vk/shader_module.h"
#include "src/ui/lib/escher/impl/vulkan_utils.h"
#include "src/ui/lib/escher/third_party/granite/vk/shader_utils.h"
namespace escher {
ShaderModule::ShaderModule(vk::Device device, ShaderStage shader_stage)
: device_(device), stage_(shader_stage) {}
ShaderModule::~ShaderModule() {
FXL_DCHECK(listeners_.empty());
if (module_) {
FXL_DCHECK(device_);
device_.destroyShaderModule(module_);
}
}
void ShaderModule::AddShaderModuleListener(ShaderModuleListener* listener) {
FXL_DCHECK(listener);
FXL_DCHECK(std::find(listeners_.begin(), listeners_.end(), listener) == listeners_.end())
<< "ShaderModule::AddShaderModuleListener(): listener already added.";
listeners_.push_back(listener);
if (is_valid()) {
listener->OnShaderModuleUpdated(this);
}
}
void ShaderModule::RemoveShaderModuleListener(ShaderModuleListener* listener) {
auto it = std::find(listeners_.begin(), listeners_.end(), listener);
FXL_DCHECK(it != listeners_.end())
<< "ShaderModule::RemoveShaderModuleListener(): listener not found.";
listeners_.erase(it);
}
void ShaderModule::RecreateModuleFromSpirvAndNotifyListeners(std::vector<uint32_t> spirv) {
FXL_DCHECK(device_);
if (module_) {
device_.destroyShaderModule(module_);
}
vk::ShaderModuleCreateInfo info;
info.codeSize = spirv.size() * sizeof(uint32_t);
info.pCode = spirv.data();
module_ = ESCHER_CHECKED_VK_RESULT(device_.createShaderModule(info));
GenerateShaderModuleResourceLayoutFromSpirv(std::move(spirv), stage_, &layout_);
for (auto listener : listeners_) {
listener->OnShaderModuleUpdated(this);
}
}
} // namespace escher