blob: b356c7ca5c332d4580887a536a6a49d1d3e06e62 [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 "lib/escher/vk/shader_module.h"
#include "lib/escher/impl/vulkan_utils.h"
#include "lib/escher/third_party/granite/vk/shader_utils.h"
namespace escher {
ShaderModule::ShaderModule(vk::Device device, ShaderStage shader_stage)
: device_(device), stage_(shader_stage) {
FXL_DCHECK(device_);
}
ShaderModule::~ShaderModule() {
FXL_DCHECK(listeners_.empty());
if (module_) {
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) {
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