Vulkan: Get rid of the empty descriptor set
This commit is contained in:
parent
8bfe22bbd7
commit
35e4431c33
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
Loading…
Reference in New Issue