blob: 3462387fbd488d74b70148660b6af1b998c7cb8d [file] [log] [blame]
/*
* Copyright 2023 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/gpu/graphite/vk/VulkanDescriptorPool.h"
#include "include/private/base/SkTArray.h"
#include "src/gpu/graphite/vk/VulkanDescriptorSet.h"
#include "src/gpu/graphite/vk/VulkanSharedContext.h"
namespace skgpu::graphite {
namespace { // anonymous namespace
static VkDescriptorType ds_type_enum_to_vk_ds(DescriptorType type) {
switch (type) {
case DescriptorType::kUniformBuffer:
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
case DescriptorType::kTextureSampler:
return VK_DESCRIPTOR_TYPE_SAMPLER;
case DescriptorType::kTexture:
return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
case DescriptorType::kCombinedTextureSampler:
return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
case DescriptorType::kStorageBuffer:
return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
case DescriptorType::kInputAttachment:
return VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
}
SkUNREACHABLE;
}
} // anonymous namespace
sk_sp<VulkanDescriptorPool> VulkanDescriptorPool::Make(
const VulkanSharedContext* context,
SkSpan<DescTypeAndCount> requestedDescCounts) {
if (requestedDescCounts.empty()) {
return nullptr;
}
// For each requested descriptor type and count, create a VkDescriptorPoolSize struct which
// specifies the descriptor type and quantity for pool creation.
skia_private::STArray<kDescriptorTypeCount, VkDescriptorPoolSize> poolSizes;
for (size_t i = 0; i < requestedDescCounts.size(); i++) {
SkASSERT(requestedDescCounts[i].count > 0);
if (requestedDescCounts[i].count > kMaxNumDescriptors) {
SkDebugf("The number of descriptors requested, %d, exceeds the maximum allowed (%d).\n",
requestedDescCounts[i].count,
kMaxNumDescriptors);
return nullptr;
}
VkDescriptorPoolSize* poolSize = &poolSizes.at(i);
memset(poolSize, 0, sizeof(VkDescriptorPoolSize));
// Map each DescriptorSetType to the appropriate backend VkDescriptorType
poolSize->type = ds_type_enum_to_vk_ds(requestedDescCounts[i].type);
// Create a pool large enough to accommodate the maximum possible number of descriptor sets
poolSize->descriptorCount = requestedDescCounts[i].count * kMaxNumSets;
}
VkDescriptorPoolCreateInfo createInfo;
memset(&createInfo, 0, sizeof(VkDescriptorPoolCreateInfo));
createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.maxSets = kMaxNumSets;
createInfo.poolSizeCount = requestedDescCounts.size();
createInfo.pPoolSizes = &poolSizes.front();
VkDescriptorPool pool;
VkResult result;
VULKAN_CALL_RESULT(context->interface(), result, CreateDescriptorPool(context->device(),
&createInfo,
nullptr,
&pool));
if (result != VK_SUCCESS) {
return nullptr;
}
return sk_sp<VulkanDescriptorPool>(new VulkanDescriptorPool(context, pool));
}
VulkanDescriptorPool::VulkanDescriptorPool(const VulkanSharedContext* context,
VkDescriptorPool pool)
: fSharedContext(context)
, fDescPool(pool) {}
VulkanDescriptorPool::~VulkanDescriptorPool() {
// Destroying the VkDescriptorPool will automatically free and delete any VkDescriptorSets
// allocated from the pool.
VULKAN_CALL(fSharedContext->interface(),
DestroyDescriptorPool(fSharedContext->device(), fDescPool, nullptr));
}
} // namespace skgpu::graphite