blob: ee82614bfd6e7db397a7a74f940759ec9e685b2f [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/descriptor_pool_vk.h"
#include "flutter/fml/trace_event.h"
#include "impeller/base/validation.h"
namespace impeller {
DescriptorPoolVK::DescriptorPoolVK(
const std::weak_ptr<const DeviceHolder>& device_holder)
: device_holder_(device_holder) {
FML_DCHECK(device_holder.lock());
}
DescriptorPoolVK::~DescriptorPoolVK() = default;
static vk::UniqueDescriptorPool CreatePool(const vk::Device& device,
uint32_t image_count,
uint32_t buffer_count) {
TRACE_EVENT0("impeller", "CreateDescriptorPool");
std::vector<vk::DescriptorPoolSize> pools = {};
if (image_count > 0) {
pools.emplace_back(vk::DescriptorPoolSize{
vk::DescriptorType::eCombinedImageSampler, image_count});
}
if (buffer_count > 0) {
pools.emplace_back(vk::DescriptorPoolSize{
vk::DescriptorType::eUniformBuffer, buffer_count});
pools.emplace_back(vk::DescriptorPoolSize{
vk::DescriptorType::eStorageBuffer, buffer_count});
}
vk::DescriptorPoolCreateInfo pool_info;
pool_info.setMaxSets(image_count + buffer_count);
pool_info.setPoolSizes(pools);
auto [result, pool] = device.createDescriptorPoolUnique(pool_info);
if (result != vk::Result::eSuccess) {
VALIDATION_LOG << "Unable to create a descriptor pool";
}
return std::move(pool);
}
fml::StatusOr<std::vector<vk::DescriptorSet>>
DescriptorPoolVK::AllocateDescriptorSets(
uint32_t buffer_count,
uint32_t sampler_count,
const std::vector<vk::DescriptorSetLayout>& layouts) {
std::shared_ptr<const DeviceHolder> strong_device = device_holder_.lock();
if (!strong_device) {
return fml::Status(fml::StatusCode::kUnknown, "No device");
}
auto new_pool =
CreatePool(strong_device->GetDevice(), sampler_count, buffer_count);
if (!new_pool) {
return fml::Status(fml::StatusCode::kUnknown,
"Failed to create descriptor pool");
}
pool_ = std::move(new_pool);
vk::DescriptorSetAllocateInfo set_info;
set_info.setDescriptorPool(pool_.get());
set_info.setSetLayouts(layouts);
auto [result, sets] =
strong_device->GetDevice().allocateDescriptorSets(set_info);
if (result != vk::Result::eSuccess) {
VALIDATION_LOG << "Could not allocate descriptor sets: "
<< vk::to_string(result);
return fml::Status(fml::StatusCode::kUnknown, "");
}
return sets;
}
} // namespace impeller