Vulkan: Get rid of the empty descriptor set

This commit is contained in:
DrChat 2017-08-07 21:46:35 -05:00
parent 8bfe22bbd7
commit 35e4431c33
2 changed files with 0 additions and 145 deletions

View File

@ -170,7 +170,6 @@ TextureCache::TextureCache(Memory* memory, RegisterFile* register_file,
invalidated_textures_ = &invalidated_textures_sets_[0]; invalidated_textures_ = &invalidated_textures_sets_[0];
device_queue_ = device_->AcquireQueue(); device_queue_ = device_->AcquireQueue();
SetupEmptySet();
} }
TextureCache::~TextureCache() { TextureCache::~TextureCache() {
@ -178,7 +177,6 @@ TextureCache::~TextureCache() {
device_->ReleaseQueue(device_queue_); device_->ReleaseQueue(device_queue_);
} }
DestroyEmptySet();
for (auto it = samplers_.begin(); it != samplers_.end(); ++it) { for (auto it = samplers_.begin(); it != samplers_.end(); ++it) {
vkDestroySampler(*device_, it->second->sampler, nullptr); vkDestroySampler(*device_, it->second->sampler, nullptr);
delete it->second; delete it->second;
@ -189,127 +187,6 @@ TextureCache::~TextureCache() {
nullptr); nullptr);
} }
void TextureCache::SetupEmptySet() {
// Create an image first.
VkImageCreateInfo image_info = {};
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
image_info.imageType = VK_IMAGE_TYPE_2D;
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
image_info.format = format;
image_info.extent = {1, 1, 1};
image_info.mipLevels = 1;
image_info.arrayLayers = 1;
image_info.samples = VK_SAMPLE_COUNT_1_BIT;
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
image_info.queueFamilyIndexCount = 0;
image_info.pQueueFamilyIndices = nullptr;
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
VkImage image;
auto err = vkCreateImage(*device_, &image_info, nullptr, &image);
CheckResult(err, "vkCreateImage");
VkMemoryRequirements mem_requirements;
vkGetImageMemoryRequirements(*device_, image, &mem_requirements);
// TODO: Use a circular buffer or something else to allocate this memory.
// The device has a limited amount (around 64) of memory allocations that we
// can make.
// Now that we have the size, back the image with GPU memory.
auto memory = device_->AllocateMemory(mem_requirements, 0);
if (!memory) {
// Crap.
assert_always();
vkDestroyImage(*device_, image, nullptr);
return;
}
err = vkBindImageMemory(*device_, image, memory, 0);
CheckResult(err, "vkBindImageMemory");
VkImageViewCreateInfo view_info;
view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
view_info.pNext = nullptr;
view_info.flags = 0;
view_info.image = image;
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_info.format = format;
view_info.components = {VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_ONE,
VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_ONE};
view_info.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
err = vkCreateImageView(*device_, &view_info, nullptr, &empty_image_view_);
CheckResult(err, "vkCreateImageView");
// Empty image is setup!
empty_image_ = image;
empty_image_memory_ = memory;
// Setup an empty sampler
VkSamplerCreateInfo sampler_info;
sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
sampler_info.pNext = nullptr;
sampler_info.flags = 0;
sampler_info.magFilter = VK_FILTER_NEAREST;
sampler_info.minFilter = VK_FILTER_NEAREST;
sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
sampler_info.mipLodBias = 0.f;
sampler_info.anisotropyEnable = VK_FALSE;
sampler_info.maxAnisotropy = 0.f;
sampler_info.compareEnable = VK_FALSE;
sampler_info.compareOp = VK_COMPARE_OP_NEVER;
sampler_info.minLod = 0.f;
sampler_info.maxLod = 0.f;
sampler_info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
sampler_info.unnormalizedCoordinates = VK_FALSE;
err = vkCreateSampler(*device_, &sampler_info, nullptr, &empty_sampler_);
CheckResult(err, "vkCreateSampler");
// Okay, allocate and setup an empty descriptor set.
VkDescriptorPool pool = descriptor_pool_->descriptor_pool();
VkDescriptorSetAllocateInfo alloc_info;
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
alloc_info.pNext = nullptr;
alloc_info.descriptorPool = pool;
alloc_info.descriptorSetCount = 1;
alloc_info.pSetLayouts = &texture_descriptor_set_layout_;
vkAllocateDescriptorSets(*device_, &alloc_info, &empty_set_);
VkWriteDescriptorSet empty_write;
empty_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
empty_write.pNext = nullptr;
empty_write.dstSet = empty_set_;
empty_write.dstBinding = 0;
empty_write.dstArrayElement = 0;
empty_write.descriptorCount = 32;
empty_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
VkDescriptorImageInfo info[32];
std::memset(info, 0, sizeof(info));
for (int i = 0; i < 32; i++) {
info[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
info[i].imageView = empty_image_view_;
info[i].sampler = empty_sampler_;
}
empty_write.pImageInfo = info;
vkUpdateDescriptorSets(*device_, 1, &empty_write, 0, nullptr);
}
void TextureCache::DestroyEmptySet() {
vkFreeDescriptorSets(*device_, descriptor_pool_->descriptor_pool(), 1,
&empty_set_);
vkDestroySampler(*device_, empty_sampler_, nullptr);
vkDestroyImageView(*device_, empty_image_view_, nullptr);
vkDestroyImage(*device_, empty_image_, nullptr);
vkFreeMemory(*device_, empty_image_memory_, nullptr);
}
TextureCache::Texture* TextureCache::AllocateTexture( TextureCache::Texture* TextureCache::AllocateTexture(
const TextureInfo& texture_info, VkFormatFeatureFlags required_flags) { const TextureInfo& texture_info, VkFormatFeatureFlags required_flags) {
// Create an image first. // Create an image first.
@ -1261,19 +1138,6 @@ VkDescriptorSet TextureCache::PrepareTextureSet(
return nullptr; return nullptr;
} }
// Copy in empty descriptors first
VkCopyDescriptorSet empty_copy;
empty_copy.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
empty_copy.pNext = nullptr;
empty_copy.srcSet = empty_set_;
empty_copy.srcBinding = 0;
empty_copy.srcArrayElement = 0;
empty_copy.dstSet = descriptor_set;
empty_copy.dstBinding = 0;
empty_copy.dstArrayElement = 0;
empty_copy.descriptorCount = 32;
vkUpdateDescriptorSets(*device_, 0, nullptr, 1, &empty_copy);
for (uint32_t i = 0; i < update_set_info->image_write_count; i++) { for (uint32_t i = 0; i < update_set_info->image_write_count; i++) {
update_set_info->image_writes[i].dstSet = descriptor_set; update_set_info->image_writes[i].dstSet = descriptor_set;
} }

View File

@ -123,9 +123,6 @@ class TextureCache {
VkSampler sampler; VkSampler sampler;
}; };
void SetupEmptySet();
void DestroyEmptySet();
// Allocates a new texture and memory to back it on the GPU. // Allocates a new texture and memory to back it on the GPU.
Texture* AllocateTexture(const TextureInfo& texture_info, Texture* AllocateTexture(const TextureInfo& texture_info,
VkFormatFeatureFlags required_flags = VkFormatFeatureFlags required_flags =
@ -183,12 +180,6 @@ class TextureCache {
std::unordered_map<uint64_t, VkDescriptorSet> texture_bindings_; std::unordered_map<uint64_t, VkDescriptorSet> texture_bindings_;
VkDescriptorSetLayout texture_descriptor_set_layout_ = nullptr; VkDescriptorSetLayout texture_descriptor_set_layout_ = nullptr;
VkImage empty_image_ = nullptr;
VkImageView empty_image_view_ = nullptr;
VkDeviceMemory empty_image_memory_ = nullptr;
VkSampler empty_sampler_ = nullptr;
VkDescriptorSet empty_set_ = nullptr;
ui::vulkan::CircularBuffer staging_buffer_; ui::vulkan::CircularBuffer staging_buffer_;
std::unordered_map<uint64_t, Texture*> textures_; std::unordered_map<uint64_t, Texture*> textures_;
std::unordered_map<uint64_t, Sampler*> samplers_; std::unordered_map<uint64_t, Sampler*> samplers_;