Vulkan: Use Correct Image Aspects

Depending on the usage of an image/image view different image aspect
requirements need to be used. When changing the layout of an image
all aspects needs to be included. When using it as a sampler or
framebuffer attachment only one aspect can be used.

This change also remove duplicated code when creating image views.

Pull Request: https://projects.blender.org/blender/blender/pulls/111349
This commit is contained in:
Jeroen Bakker 2023-08-22 11:00:43 +02:00
parent 8bae4427ed
commit 2af2a11651
5 changed files with 44 additions and 66 deletions

View File

@ -58,9 +58,12 @@ VkImageAspectFlagBits to_vk_image_aspect_flag_bits(const eGPUTextureFormat forma
case GPU_DEPTH_COMPONENT32F:
case GPU_DEPTH_COMPONENT24:
case GPU_DEPTH_COMPONENT16:
return VK_IMAGE_ASPECT_DEPTH_BIT;
case GPU_DEPTH32F_STENCIL8:
case GPU_DEPTH24_STENCIL8:
return VK_IMAGE_ASPECT_DEPTH_BIT;
return static_cast<VkImageAspectFlagBits>(VK_IMAGE_ASPECT_DEPTH_BIT |
VK_IMAGE_ASPECT_STENCIL_BIT);
/* Texture only formats. */
case GPU_RGB32UI:

View File

@ -405,7 +405,11 @@ void VKFrameBuffer::render_pass_create()
/* Ensure texture is allocated to ensure the image view. */
VKTexture &texture = *static_cast<VKTexture *>(unwrap(attachment.tex));
texture.ensure_allocated();
image_views_.append(VKImageView(texture, attachment.layer, attachment.mip, name_));
image_views_.append(VKImageView(texture,
eImageViewUsage::Attachment,
IndexRange(max_ii(attachment.layer, 0), 1),
IndexRange(attachment.mip, 1),
name_));
image_views[attachment_location] = image_views_.last().vk_handle();
VkAttachmentDescription &attachment_description =

View File

@ -15,15 +15,34 @@
namespace blender::gpu {
VKImageView::VKImageView(VKTexture &texture, int layer, int mip_level, StringRefNull name)
: vk_image_view_(create_vk_image_view(texture, layer, mip_level, name))
VKImageView::VKImageView(VKTexture &texture,
eImageViewUsage usage,
IndexRange layer_range,
IndexRange mip_range,
StringRefNull name)
{
BLI_assert(vk_image_view_ != VK_NULL_HANDLE);
}
const VkImageAspectFlagBits allowed_bits = static_cast<VkImageAspectFlagBits>(
VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT);
VkImageAspectFlagBits image_aspect = static_cast<VkImageAspectFlagBits>(
(to_vk_image_aspect_flag_bits(texture.format_get()) & allowed_bits));
VKImageView::VKImageView(VkImageView vk_image_view) : vk_image_view_(vk_image_view)
{
BLI_assert(vk_image_view_ != VK_NULL_HANDLE);
VK_ALLOCATION_CALLBACKS
VkImageViewCreateInfo image_view_info = {};
image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
image_view_info.image = texture.vk_image_handle();
image_view_info.viewType = to_vk_image_view_type(texture.type_get(), usage);
image_view_info.format = to_vk_format(texture.format_get());
image_view_info.components = to_vk_component_mapping(texture.format_get());
image_view_info.subresourceRange.aspectMask = image_aspect;
image_view_info.subresourceRange.baseMipLevel = mip_range.first();
image_view_info.subresourceRange.levelCount = mip_range.size();
image_view_info.subresourceRange.baseArrayLayer = layer_range.first();
image_view_info.subresourceRange.layerCount = layer_range.size();
const VKDevice &device = VKBackend::get().device_get();
vkCreateImageView(
device.device_get(), &image_view_info, vk_allocation_callbacks, &vk_image_view_);
debug::object_label(vk_image_view_, name.c_str());
}
VKImageView::VKImageView(VKImageView &&other)
@ -40,31 +59,5 @@ VKImageView::~VKImageView()
vkDestroyImageView(device.device_get(), vk_image_view_, vk_allocation_callbacks);
}
}
VkImageView VKImageView::create_vk_image_view(VKTexture &texture,
int layer,
int mip_level,
StringRefNull name)
{
VK_ALLOCATION_CALLBACKS
VkImageViewCreateInfo image_view_info = {};
image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
image_view_info.image = texture.vk_image_handle();
image_view_info.viewType = to_vk_image_view_type(texture.type_get(),
eImageViewUsage::Attachment);
image_view_info.format = to_vk_format(texture.format_get());
image_view_info.components = to_vk_component_mapping(texture.format_get());
image_view_info.subresourceRange.aspectMask = to_vk_image_aspect_flag_bits(texture.format_get());
image_view_info.subresourceRange.baseMipLevel = mip_level;
image_view_info.subresourceRange.levelCount = 1;
image_view_info.subresourceRange.baseArrayLayer = layer == -1 ? 0 : layer;
image_view_info.subresourceRange.layerCount = 1;
const VKDevice &device = VKBackend::get().device_get();
VkImageView image_view = VK_NULL_HANDLE;
vkCreateImageView(device.device_get(), &image_view_info, vk_allocation_callbacks, &image_view);
debug::object_label(image_view, name.c_str());
return image_view;
}
} // namespace blender::gpu

View File

@ -20,13 +20,11 @@ class VKImageView : NonCopyable {
VkImageView vk_image_view_ = VK_NULL_HANDLE;
public:
VKImageView(VKTexture &texture, int layer, int mip_level, StringRefNull name);
/**
* Wrap the given vk_image_view handle. Note that the vk_image_view handle ownership is
* transferred to VKImageView.
*/
VKImageView(VkImageView vk_image_view);
VKImageView(VKTexture &texture,
eImageViewUsage usage,
IndexRange layer_range,
IndexRange mip_range,
StringRefNull name);
VKImageView(VKImageView &&other);
~VKImageView();
@ -36,12 +34,6 @@ class VKImageView : NonCopyable {
BLI_assert(vk_image_view_ != VK_NULL_HANDLE);
return vk_image_view_;
}
private:
static VkImageView create_vk_image_view(VKTexture &texture,
int layer,
int mip_level,
StringRefNull name);
};
} // namespace blender::gpu

View File

@ -543,25 +543,11 @@ void VKTexture::image_view_ensure()
void VKTexture::image_view_update()
{
VK_ALLOCATION_CALLBACKS
VkImageViewCreateInfo image_view_info = {};
image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
image_view_info.image = vk_image_;
image_view_info.viewType = to_vk_image_view_type(type_, eImageViewUsage::ShaderBinding);
image_view_info.format = to_vk_format(format_);
image_view_info.components = to_vk_component_mapping(format_);
image_view_info.subresourceRange.aspectMask = to_vk_image_aspect_flag_bits(format_);
IndexRange mip_range = mip_map_range();
image_view_info.subresourceRange.baseMipLevel = mip_range.first();
image_view_info.subresourceRange.levelCount = mip_range.size();
image_view_info.subresourceRange.layerCount =
ELEM(type_, GPU_TEXTURE_CUBE, GPU_TEXTURE_CUBE_ARRAY) ? d_ : VK_REMAINING_ARRAY_LAYERS;
const VKDevice &device = VKBackend::get().device_get();
VkImageView image_view = VK_NULL_HANDLE;
vkCreateImageView(device.device_get(), &image_view_info, vk_allocation_callbacks, &image_view);
debug::object_label(image_view, name_);
image_view_.emplace(image_view);
IndexRange layer_range(
0, ELEM(type_, GPU_TEXTURE_CUBE, GPU_TEXTURE_CUBE_ARRAY) ? d_ : VK_REMAINING_ARRAY_LAYERS);
image_view_.emplace(
VKImageView(*this, eImageViewUsage::ShaderBinding, layer_range, mip_range, name_));
}
IndexRange VKTexture::mip_map_range() const