From 26c123293a6e662c590636b1042af8f27e0ad6aa Mon Sep 17 00:00:00 2001 From: Alexey Panteleev Date: Tue, 15 Aug 2023 17:30:31 -0700 Subject: [PATCH] Implemented view formats and the isTypeless texture flag on Vulkan. --- src/vulkan/vulkan-backend.h | 10 +++--- src/vulkan/vulkan-graphics.cpp | 6 ++-- src/vulkan/vulkan-resource-bindings.cpp | 8 ++--- src/vulkan/vulkan-texture.cpp | 46 +++++++++++-------------- 4 files changed, 33 insertions(+), 37 deletions(-) diff --git a/src/vulkan/vulkan-backend.h b/src/vulkan/vulkan-backend.h index b44b66f..73b143a 100644 --- a/src/vulkan/vulkan-backend.h +++ b/src/vulkan/vulkan-backend.h @@ -365,9 +365,9 @@ namespace nvrhi::vulkan struct Hash { - std::size_t operator()(std::tuple const& s) const noexcept + std::size_t operator()(std::tuple const& s) const noexcept { - const auto& [subresources, viewType, dimension] = s; + const auto& [subresources, viewType, dimension, format] = s; size_t hash = 0; @@ -377,6 +377,7 @@ namespace nvrhi::vulkan hash_combine(hash, subresources.numArraySlices); hash_combine(hash, viewType); hash_combine(hash, dimension); + hash_combine(hash, format); return hash; } @@ -395,7 +396,7 @@ namespace nvrhi::vulkan // contains subresource views for this texture // note that we only create the views that the app uses, and that multiple views may map to the same subresources - std::unordered_map, TextureSubresourceView, Texture::Hash> subresourceViews; + std::unordered_map, TextureSubresourceView, Texture::Hash> subresourceViews; Texture(const VulkanContext& context, VulkanAllocator& allocator) : TextureStateExtension(desc) @@ -406,7 +407,8 @@ namespace nvrhi::vulkan // returns a subresource view for an arbitrary range of mip levels and array layers. // 'viewtype' only matters when asking for a depthstencil view; in situations where only depth or stencil can be bound // (such as an SRV with ImageLayout::eShaderReadOnlyOptimal), but not both, then this specifies which of the two aspect bits is to be set. - TextureSubresourceView& getSubresourceView(const TextureSubresourceSet& subresources, TextureDimension dimension, TextureSubresourceViewType viewtype = TextureSubresourceViewType::AllAspects); + TextureSubresourceView& getSubresourceView(const TextureSubresourceSet& subresources, TextureDimension dimension, + Format format, TextureSubresourceViewType viewtype = TextureSubresourceViewType::AllAspects); uint32_t getNumSubresources() const; uint32_t getSubresourceIndex(uint32_t mipLevel, uint32_t arrayLayer) const; diff --git a/src/vulkan/vulkan-graphics.cpp b/src/vulkan/vulkan-graphics.cpp index cb42abb..a61d3b4 100644 --- a/src/vulkan/vulkan-graphics.cpp +++ b/src/vulkan/vulkan-graphics.cpp @@ -98,7 +98,7 @@ namespace nvrhi::vulkan TextureDimension dimension = getDimensionForFramebuffer(t->desc.dimension, subresources.numArraySlices > 1); - const auto& view = t->getSubresourceView(subresources, dimension); + const auto& view = t->getSubresourceView(subresources, dimension, rt.format); attachmentViews[i] = view.view; fb->resources.push_back(rt.texture); @@ -141,7 +141,7 @@ namespace nvrhi::vulkan TextureDimension dimension = getDimensionForFramebuffer(texture->desc.dimension, subresources.numArraySlices > 1); - const auto& view = texture->getSubresourceView(subresources, dimension); + const auto& view = texture->getSubresourceView(subresources, dimension, att.format); attachmentViews.push_back(view.view); fb->resources.push_back(att.texture); @@ -182,7 +182,7 @@ namespace nvrhi::vulkan TextureSubresourceSet subresources = vrsAttachment.subresources.resolve(vrsTexture->desc, true); TextureDimension dimension = getDimensionForFramebuffer(vrsTexture->desc.dimension, subresources.numArraySlices > 1); - const auto& view = vrsTexture->getSubresourceView(subresources, dimension); + const auto& view = vrsTexture->getSubresourceView(subresources, dimension, vrsAttachment.format); attachmentViews.push_back(view.view); fb->resources.push_back(vrsAttachment.texture); diff --git a/src/vulkan/vulkan-resource-bindings.cpp b/src/vulkan/vulkan-resource-bindings.cpp index 3b5b044..0f1ef04 100644 --- a/src/vulkan/vulkan-resource-bindings.cpp +++ b/src/vulkan/vulkan-resource-bindings.cpp @@ -384,7 +384,7 @@ namespace nvrhi::vulkan const auto subresource = binding.subresources.resolve(texture->desc, false); const auto textureViewType = getTextureViewType(binding.format, texture->desc.format); - auto& view = texture->getSubresourceView(subresource, binding.dimension, textureViewType); + auto& view = texture->getSubresourceView(subresource, binding.dimension, binding.format, textureViewType); auto& imageInfo = descriptorImageInfo.emplace_back(); imageInfo = vk::DescriptorImageInfo() @@ -411,7 +411,7 @@ namespace nvrhi::vulkan const auto subresource = binding.subresources.resolve(texture->desc, true); const auto textureViewType = getTextureViewType(binding.format, texture->desc.format); - auto& view = texture->getSubresourceView(subresource, binding.dimension, textureViewType); + auto& view = texture->getSubresourceView(subresource, binding.dimension, binding.format, textureViewType); auto& imageInfo = descriptorImageInfo.emplace_back(); imageInfo = vk::DescriptorImageInfo() @@ -729,7 +729,7 @@ namespace nvrhi::vulkan const auto subresource = binding.subresources.resolve(texture->desc, false); const auto textureViewType = getTextureViewType(binding.format, texture->desc.format); - auto& view = texture->getSubresourceView(subresource, binding.dimension, textureViewType); + auto& view = texture->getSubresourceView(subresource, binding.dimension, binding.format, textureViewType); auto& imageInfo = descriptorImageInfo.emplace_back(); imageInfo = vk::DescriptorImageInfo() @@ -749,7 +749,7 @@ namespace nvrhi::vulkan const auto subresource = binding.subresources.resolve(texture->desc, true); const auto textureViewType = getTextureViewType(binding.format, texture->desc.format); - auto& view = texture->getSubresourceView(subresource, binding.dimension, textureViewType); + auto& view = texture->getSubresourceView(subresource, binding.dimension, binding.format, textureViewType); auto& imageInfo = descriptorImageInfo.emplace_back(); imageInfo = vk::DescriptorImageInfo() diff --git a/src/vulkan/vulkan-texture.cpp b/src/vulkan/vulkan-texture.cpp index 3ed76fc..1a1678e 100644 --- a/src/vulkan/vulkan-texture.cpp +++ b/src/vulkan/vulkan-texture.cpp @@ -201,28 +201,18 @@ namespace nvrhi::vulkan return flags; } - vk::ImageCreateFlagBits pickImageFlags(const TextureDesc& d) + vk::ImageCreateFlags pickImageFlags(const TextureDesc& d) { - switch (d.dimension) - { - case TextureDimension::TextureCube: - case TextureDimension::TextureCubeArray: - return vk::ImageCreateFlagBits::eCubeCompatible; + vk::ImageCreateFlags flags = vk::ImageCreateFlags(0); - case TextureDimension::Texture2DArray: - case TextureDimension::Texture2DMSArray: - case TextureDimension::Texture1DArray: - case TextureDimension::Texture1D: - case TextureDimension::Texture2D: - case TextureDimension::Texture3D: - case TextureDimension::Texture2DMS: - return (vk::ImageCreateFlagBits)0; + if (d.dimension == TextureDimension::TextureCube || + d.dimension == TextureDimension::TextureCubeArray) + flags |= vk::ImageCreateFlagBits::eCubeCompatible; - case TextureDimension::Unknown: - default: - utils::InvalidEnum(); - return (vk::ImageCreateFlagBits)0; - } + if (d.isTypeless) + flags |= vk::ImageCreateFlagBits::eMutableFormat; + + return flags; } // fills out all info fields in Texture based on a TextureDesc @@ -236,7 +226,7 @@ namespace nvrhi::vulkan vk::Format format = vk::Format(convertFormat(desc.format)); vk::ImageUsageFlags usage = pickImageUsage(desc); vk::SampleCountFlagBits sampleCount = pickImageSampleCount(desc); - vk::ImageCreateFlagBits flags = pickImageFlags(desc); + vk::ImageCreateFlags flags = pickImageFlags(desc); texture->imageInfo = vk::ImageCreateInfo() .setImageType(type) @@ -263,7 +253,8 @@ namespace nvrhi::vulkan texture->imageInfo.setPNext(&texture->externalMemoryImageInfo); } - TextureSubresourceView& Texture::getSubresourceView(const TextureSubresourceSet& subresource, TextureDimension dimension, TextureSubresourceViewType viewtype) + TextureSubresourceView& Texture::getSubresourceView(const TextureSubresourceSet& subresource, TextureDimension dimension, + Format format, TextureSubresourceViewType viewtype) { // This function is called from createBindingSet etc. and therefore free-threaded. // It modifies the subresourceViews map associated with the texture. @@ -272,7 +263,10 @@ namespace nvrhi::vulkan if (dimension == TextureDimension::Unknown) dimension = desc.dimension; - auto cachekey = std::make_tuple(subresource,viewtype, dimension); + if (format == Format::UNKNOWN) + format = desc.format; + + auto cachekey = std::make_tuple(subresource, viewtype, dimension, format); auto iter = subresourceViews.find(cachekey); if (iter != subresourceViews.end()) { @@ -284,7 +278,7 @@ namespace nvrhi::vulkan view.subresource = subresource; - auto vkformat = nvrhi::vulkan::convertFormat(desc.format); + auto vkformat = nvrhi::vulkan::convertFormat(format); vk::ImageAspectFlags aspectflags = guessSubresourceImageAspectFlags(vkformat, viewtype); view.subresourceRange = vk::ImageSubresourceRange() @@ -401,14 +395,14 @@ namespace nvrhi::vulkan resolvedSrcSlice.arraySlice, 1 ); - const auto& srcSubresourceView = src->getSubresourceView(srcSubresource, TextureDimension::Unknown); + const auto& srcSubresourceView = src->getSubresourceView(srcSubresource, TextureDimension::Unknown, Format::UNKNOWN); TextureSubresourceSet dstSubresource = TextureSubresourceSet( resolvedDstSlice.mipLevel, 1, resolvedDstSlice.arraySlice, 1 ); - const auto& dstSubresourceView = dst->getSubresourceView(dstSubresource, TextureDimension::Unknown); + const auto& dstSubresourceView = dst->getSubresourceView(dstSubresource, TextureDimension::Unknown, Format::UNKNOWN); auto imageCopy = vk::ImageCopy() .setSrcSubresource(vk::ImageSubresourceLayers() @@ -683,7 +677,7 @@ namespace nvrhi::vulkan else if(!formatInfo.hasDepth && formatInfo.hasStencil) viewType = TextureSubresourceViewType::StencilOnly; - return Object(getSubresourceView(subresources, dimension, viewType).view); + return Object(getSubresourceView(subresources, dimension, format, viewType).view); } default: return nullptr;