fix: alot of stuff changed. Mostly bugfixxes / architechture changes
This commit is contained in:
@@ -1,21 +1,64 @@
|
||||
#include <destrum/Graphics/BindlessSetManager.h>
|
||||
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <volk.h>
|
||||
|
||||
#include <destrum/Graphics/Util.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr std::uint32_t maxBindlessResources = 16536;
|
||||
constexpr std::uint32_t requestedMaxBindlessResources = 16536;
|
||||
constexpr std::uint32_t maxSamplers = 32;
|
||||
|
||||
constexpr std::uint32_t texturesBinding = 0;
|
||||
constexpr std::uint32_t samplersBinding = 1;
|
||||
}
|
||||
|
||||
void BindlessSetManager::init(VkDevice device, float maxAnisotropy)
|
||||
void BindlessSetManager::init(
|
||||
VkDevice device,
|
||||
VkPhysicalDevice physicalDevice,
|
||||
float maxAnisotropy)
|
||||
{
|
||||
try {
|
||||
VkPhysicalDeviceDescriptorIndexingProperties indexingProperties{
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES,
|
||||
};
|
||||
VkPhysicalDeviceMaintenance3Properties maintenanceProperties{
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES,
|
||||
.pNext = &indexingProperties,
|
||||
};
|
||||
VkPhysicalDeviceProperties2 properties{
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
|
||||
.pNext = &maintenanceProperties,
|
||||
};
|
||||
vkGetPhysicalDeviceProperties2(physicalDevice, &properties);
|
||||
|
||||
if (indexingProperties.maxDescriptorSetUpdateAfterBindSamplers < maxSamplers ||
|
||||
indexingProperties.maxPerStageDescriptorUpdateAfterBindSamplers < maxSamplers) {
|
||||
throw std::runtime_error("The device exposes too few bindless samplers");
|
||||
}
|
||||
|
||||
const auto descriptorCapacityAfterSamplers = [](std::uint32_t capacity) {
|
||||
return capacity > maxSamplers ? capacity - maxSamplers : 0u;
|
||||
};
|
||||
const auto maxPerSetImages = descriptorCapacityAfterSamplers(
|
||||
maintenanceProperties.maxPerSetDescriptors);
|
||||
const auto maxAllPoolsImages = descriptorCapacityAfterSamplers(
|
||||
indexingProperties.maxUpdateAfterBindDescriptorsInAllPools);
|
||||
maxBindlessResources = std::min(
|
||||
requestedMaxBindlessResources,
|
||||
std::min({
|
||||
indexingProperties.maxDescriptorSetUpdateAfterBindSampledImages,
|
||||
indexingProperties.maxPerStageDescriptorUpdateAfterBindSampledImages,
|
||||
maxPerSetImages,
|
||||
maxAllPoolsImages,
|
||||
}));
|
||||
if (maxBindlessResources == 0) {
|
||||
throw std::runtime_error("The device exposes no bindless sampled-image capacity");
|
||||
}
|
||||
|
||||
{ // create pool
|
||||
const auto poolSizesBindless = std::array<VkDescriptorPoolSize, 2>{{
|
||||
{VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, maxBindlessResources},
|
||||
@@ -25,7 +68,7 @@ void BindlessSetManager::init(VkDevice device, float maxAnisotropy)
|
||||
const auto poolInfo = VkDescriptorPoolCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||
.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT,
|
||||
.maxSets = 10,
|
||||
.maxSets = 1,
|
||||
.poolSizeCount = static_cast<std::uint32_t>(poolSizesBindless.size()),
|
||||
.pPoolSizes = poolSizesBindless.data(),
|
||||
};
|
||||
@@ -78,17 +121,14 @@ void BindlessSetManager::init(VkDevice device, float maxAnisotropy)
|
||||
.pSetLayouts = &descSetLayout,
|
||||
};
|
||||
|
||||
std::uint32_t maxBinding = maxBindlessResources - 1;
|
||||
const auto countInfo = VkDescriptorSetVariableDescriptorCountAllocateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
|
||||
.descriptorSetCount = 1,
|
||||
.pDescriptorCounts = &maxBinding,
|
||||
};
|
||||
|
||||
VK_CHECK(vkAllocateDescriptorSets(device, &allocInfo, &descSet));
|
||||
}
|
||||
|
||||
initDefaultSamplers(device, maxAnisotropy);
|
||||
initDefaultSamplers(device, maxAnisotropy);
|
||||
} catch (...) {
|
||||
cleanup(device);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void BindlessSetManager::initDefaultSamplers(VkDevice device, float maxAnisotropy)
|
||||
@@ -96,7 +136,8 @@ void BindlessSetManager::initDefaultSamplers(VkDevice device, float maxAnisotrop
|
||||
// Keep in sync with bindless.glsl
|
||||
static const std::uint32_t nearestSamplerId = 0;
|
||||
static const std::uint32_t linearSamplerId = 1;
|
||||
static const std::uint32_t shadowSamplerId = 2;
|
||||
static const std::uint32_t anisotropicSamplerId = 2;
|
||||
static const std::uint32_t shadowSamplerId = 3;
|
||||
|
||||
{ // init nearest sampler
|
||||
const auto samplerCreateInfo = VkSamplerCreateInfo{
|
||||
@@ -115,15 +156,26 @@ void BindlessSetManager::initDefaultSamplers(VkDevice device, float maxAnisotrop
|
||||
.magFilter = VK_FILTER_LINEAR,
|
||||
.minFilter = VK_FILTER_LINEAR,
|
||||
.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR,
|
||||
// TODO: make possible to disable anisotropy or set other values?
|
||||
.anisotropyEnable = VK_TRUE,
|
||||
.maxAnisotropy = maxAnisotropy,
|
||||
};
|
||||
VK_CHECK(vkCreateSampler(device, &samplerCreateInfo, nullptr, &linearSampler));
|
||||
vkutil::addDebugLabel(device, linearSampler, "linear");
|
||||
addSampler(device, linearSamplerId, linearSampler);
|
||||
}
|
||||
|
||||
{ // init anisotropic sampler
|
||||
const auto samplerCreateInfo = VkSamplerCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
.magFilter = VK_FILTER_LINEAR,
|
||||
.minFilter = VK_FILTER_LINEAR,
|
||||
.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR,
|
||||
.anisotropyEnable = VK_TRUE,
|
||||
.maxAnisotropy = maxAnisotropy,
|
||||
};
|
||||
VK_CHECK(vkCreateSampler(device, &samplerCreateInfo, nullptr, &anisotropicSampler));
|
||||
vkutil::addDebugLabel(device, anisotropicSampler, "anisotropic");
|
||||
addSampler(device, anisotropicSamplerId, anisotropicSampler);
|
||||
}
|
||||
|
||||
{ // init shadow map sampler
|
||||
const auto samplerCreateInfo = VkSamplerCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
@@ -140,12 +192,47 @@ void BindlessSetManager::initDefaultSamplers(VkDevice device, float maxAnisotrop
|
||||
|
||||
void BindlessSetManager::cleanup(VkDevice device)
|
||||
{
|
||||
vkDestroySampler(device, nearestSampler, nullptr);
|
||||
vkDestroySampler(device, linearSampler, nullptr);
|
||||
vkDestroySampler(device, shadowMapSampler, nullptr);
|
||||
if (descPool != VK_NULL_HANDLE) {
|
||||
if (device != VK_NULL_HANDLE) {
|
||||
vkDestroyDescriptorPool(device, descPool, nullptr);
|
||||
}
|
||||
descPool = VK_NULL_HANDLE;
|
||||
}
|
||||
descSet = VK_NULL_HANDLE;
|
||||
|
||||
vkDestroyDescriptorSetLayout(device, descSetLayout, nullptr);
|
||||
vkDestroyDescriptorPool(device, descPool, nullptr);
|
||||
if (descSetLayout != VK_NULL_HANDLE) {
|
||||
if (device != VK_NULL_HANDLE) {
|
||||
vkDestroyDescriptorSetLayout(device, descSetLayout, nullptr);
|
||||
}
|
||||
descSetLayout = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (nearestSampler != VK_NULL_HANDLE) {
|
||||
if (device != VK_NULL_HANDLE) {
|
||||
vkDestroySampler(device, nearestSampler, nullptr);
|
||||
}
|
||||
nearestSampler = VK_NULL_HANDLE;
|
||||
}
|
||||
if (linearSampler != VK_NULL_HANDLE) {
|
||||
if (device != VK_NULL_HANDLE) {
|
||||
vkDestroySampler(device, linearSampler, nullptr);
|
||||
}
|
||||
linearSampler = VK_NULL_HANDLE;
|
||||
}
|
||||
if (anisotropicSampler != VK_NULL_HANDLE) {
|
||||
if (device != VK_NULL_HANDLE) {
|
||||
vkDestroySampler(device, anisotropicSampler, nullptr);
|
||||
}
|
||||
anisotropicSampler = VK_NULL_HANDLE;
|
||||
}
|
||||
if (shadowMapSampler != VK_NULL_HANDLE) {
|
||||
if (device != VK_NULL_HANDLE) {
|
||||
vkDestroySampler(device, shadowMapSampler, nullptr);
|
||||
}
|
||||
shadowMapSampler = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
maxBindlessResources = 0;
|
||||
}
|
||||
|
||||
void BindlessSetManager::addImage(
|
||||
@@ -153,8 +240,12 @@ void BindlessSetManager::addImage(
|
||||
std::uint32_t id,
|
||||
const VkImageView imageView)
|
||||
{
|
||||
if (id >= maxBindlessResources) {
|
||||
throw std::out_of_range("Bindless image descriptor capacity exceeded");
|
||||
}
|
||||
|
||||
const auto imageInfo = VkDescriptorImageInfo{
|
||||
.imageView = imageView, .imageLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL};
|
||||
.imageView = imageView, .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
|
||||
const auto writeSet = VkWriteDescriptorSet{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = descSet,
|
||||
@@ -170,7 +261,7 @@ void BindlessSetManager::addImage(
|
||||
void BindlessSetManager::addSampler(const VkDevice device, std::uint32_t id, VkSampler sampler)
|
||||
{
|
||||
const auto imageInfo =
|
||||
VkDescriptorImageInfo{.sampler = sampler, .imageLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL};
|
||||
VkDescriptorImageInfo{.sampler = sampler, .imageLayout = VK_IMAGE_LAYOUT_UNDEFINED};
|
||||
const auto writeSet = VkWriteDescriptorSet{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = descSet,
|
||||
|
||||
Reference in New Issue
Block a user