Skip to content

Commit

Permalink
Implemented view formats and the isTypeless texture flag on Vulkan.
Browse files Browse the repository at this point in the history
  • Loading branch information
apanteleev committed Aug 16, 2023
1 parent c74d454 commit 26c1232
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 37 deletions.
10 changes: 6 additions & 4 deletions src/vulkan/vulkan-backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,9 @@ namespace nvrhi::vulkan

struct Hash
{
std::size_t operator()(std::tuple<TextureSubresourceSet, TextureSubresourceViewType, TextureDimension> const& s) const noexcept
std::size_t operator()(std::tuple<TextureSubresourceSet, TextureSubresourceViewType, TextureDimension, Format> const& s) const noexcept
{
const auto& [subresources, viewType, dimension] = s;
const auto& [subresources, viewType, dimension, format] = s;

size_t hash = 0;

Expand All @@ -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;
}
Expand All @@ -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<std::tuple<TextureSubresourceSet, TextureSubresourceViewType, TextureDimension>, TextureSubresourceView, Texture::Hash> subresourceViews;
std::unordered_map<std::tuple<TextureSubresourceSet, TextureSubresourceViewType, TextureDimension, Format>, TextureSubresourceView, Texture::Hash> subresourceViews;

Texture(const VulkanContext& context, VulkanAllocator& allocator)
: TextureStateExtension(desc)
Expand All @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions src/vulkan/vulkan-graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions src/vulkan/vulkan-resource-bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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()
Expand Down Expand Up @@ -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()
Expand All @@ -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()
Expand Down
46 changes: 20 additions & 26 deletions src/vulkan/vulkan-texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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.
Expand All @@ -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())
{
Expand All @@ -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()
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 26c1232

Please sign in to comment.