Files
Vulkan-Samples/framework/core/image_view.cpp
T
2025-09-04 10:54:47 +08:00

123 lines
3.4 KiB
C++

/* Copyright (c) 2019-2024, Arm Limited and Contributors
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "image_view.h"
#include "core/image.h"
#include "device.h"
namespace vkb
{
namespace core
{
ImageView::ImageView(Image &img, VkImageViewType view_type, VkFormat format,
uint32_t mip_level, uint32_t array_layer,
uint32_t n_mip_levels, uint32_t n_array_layers) :
VulkanResource{VK_NULL_HANDLE, &img.get_device()},
image{&img},
format{format}
{
if (format == VK_FORMAT_UNDEFINED)
{
this->format = format = image->get_format();
}
subresource_range.baseMipLevel = mip_level;
subresource_range.baseArrayLayer = array_layer;
subresource_range.levelCount = n_mip_levels == 0 ? image->get_subresource().mipLevel : n_mip_levels;
subresource_range.layerCount = n_array_layers == 0 ? image->get_subresource().arrayLayer : n_array_layers;
if (is_depth_format(format))
{
subresource_range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
}
else
{
subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
}
VkImageViewCreateInfo view_info{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
view_info.image = image->get_handle();
view_info.viewType = view_type;
view_info.format = format;
view_info.subresourceRange = subresource_range;
auto result = vkCreateImageView(get_device().get_handle(), &view_info, nullptr, &get_handle());
if (result != VK_SUCCESS)
{
throw VulkanException{result, "Cannot create ImageView"};
}
// Register this image view to its image
// in order to be notified when it gets moved
image->get_views().emplace(this);
}
ImageView::ImageView(ImageView &&other) :
VulkanResource{std::move(other)},
image{other.image},
format{other.format},
subresource_range{other.subresource_range}
{
// Remove old view from image set and add this new one
auto &views = image->get_views();
views.erase(&other);
views.emplace(this);
}
ImageView::~ImageView()
{
if (has_device())
{
vkDestroyImageView(get_device().get_handle(), get_handle(), nullptr);
}
}
const Image &ImageView::get_image() const
{
assert(image && "Image view is referring an invalid image");
return *image;
}
void ImageView::set_image(Image &img)
{
image = &img;
}
VkFormat ImageView::get_format() const
{
return format;
}
VkImageSubresourceRange ImageView::get_subresource_range() const
{
return subresource_range;
}
VkImageSubresourceLayers ImageView::get_subresource_layers() const
{
VkImageSubresourceLayers subresource{};
subresource.aspectMask = subresource_range.aspectMask;
subresource.baseArrayLayer = subresource_range.baseArrayLayer;
subresource.layerCount = subresource_range.layerCount;
subresource.mipLevel = subresource_range.baseMipLevel;
return subresource;
}
} // namespace core
} // namespace vkb