vk: Add support for derived image views

This commit is contained in:
kd-11 2026-02-22 18:14:06 +03:00 committed by kd-11
parent f2a17e4898
commit 4c20bdcc9f
5 changed files with 54 additions and 10 deletions

View file

@ -45,7 +45,7 @@ namespace vk
for (const auto& e : image_list)
{
const VkImageSubresourceRange subres = { e->aspect(), 0, 1, 0, 1 };
image_views.push_back(std::make_unique<vk::image_view>(dev, e, VK_IMAGE_VIEW_TYPE_2D, vk::default_component_map, subres));
image_views.push_back(std::make_unique<vk::image_view>(dev, e, e->format(), VK_IMAGE_VIEW_TYPE_2D, vk::default_component_map, subres));
}
auto value = std::make_unique<vk::framebuffer_holder>(dev, renderpass, width, height, std::move(image_views));

View file

@ -911,15 +911,15 @@ namespace vk
m_cyclic_ref_tracker.reset();
}
image_view* render_target::get_view(const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask)
image_view* render_target::get_view(VkFormat format, const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask)
{
if (remap.encoded == VK_REMAP_VIEW_MULTISAMPLED)
{
// Special remap flag, intercept here
return vk::viewable_image::get_view(remap.with_encoding(VK_REMAP_IDENTITY), mask);
return vk::viewable_image::get_view(format, remap.with_encoding(VK_REMAP_IDENTITY), mask);
}
return vk::viewable_image::get_view(remap, mask);
return vk::viewable_image::get_view(format, remap, mask);
}
void render_target::memory_barrier(vk::command_buffer& cmd, rsx::surface_access access)

View file

@ -110,7 +110,7 @@ namespace vk
bool matches_dimensions(u16 _width, u16 _height) const;
void reset_surface_counters();
image_view* get_view(const rsx::texture_channel_remap_t& remap,
image_view* get_view(VkFormat format, const rsx::texture_channel_remap_t& remap,
VkImageAspectFlags mask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT) override;
// Memory management

View file

@ -333,10 +333,10 @@ namespace vk
create_impl();
}
image_view::image_view(VkDevice dev, vk::image* resource, VkImageViewType view_type, const VkComponentMapping& mapping, const VkImageSubresourceRange& range)
image_view::image_view(VkDevice dev, vk::image* resource, VkFormat format, VkImageViewType view_type, const VkComponentMapping& mapping, const VkImageSubresourceRange& range)
: m_device(dev), m_resource(resource)
{
info.format = resource->info.format;
info.format = format == VK_FORMAT_UNDEFINED ? resource->format() : format;
info.image = resource->value;
info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
info.components = mapping;
@ -379,6 +379,33 @@ namespace vk
vkDestroyImageView(m_device, value, nullptr);
}
image_view* image_view::as(VkFormat format)
{
if (this->format() == format)
{
return this;
}
auto self = this->m_root_view
? this->m_root_view
: this;
if (auto found = self->m_subviews.find(format);
found != self->m_subviews.end())
{
return found->second.get();
}
// Create a derived
auto view = std::make_unique<image_view>(m_device, info.image, info.viewType, format, info.components, info.subresourceRange);
view->m_resource = self->m_resource;
view->m_root_view = self;
auto ret = view.get();
self->m_subviews.emplace(format, std::move(view));
return ret;
}
u32 image_view::encoded_component_map() const
{
#if (VK_DISABLE_COMPONENT_SWIZZLE)
@ -436,7 +463,7 @@ namespace vk
return result;
}
image_view* viewable_image::get_view(const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask)
image_view* viewable_image::get_view(VkFormat format, const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask)
{
u32 remap_encoding = remap.encoded;
if (remap_encoding == VK_REMAP_IDENTITY)
@ -479,7 +506,7 @@ namespace vk
const VkImageSubresourceRange range = { aspect() & mask, 0, info.mipLevels, 0, info.arrayLayers };
ensure(range.aspectMask);
auto view = std::make_unique<vk::image_view>(*g_render_device, this, VK_IMAGE_VIEW_TYPE_MAX_ENUM, real_mapping, range);
auto view = std::make_unique<vk::image_view>(*g_render_device, this, format, VK_IMAGE_VIEW_TYPE_MAX_ENUM, real_mapping, range);
auto result = view.get();
views.emplace(storage_key, std::move(view));
return result;

View file

@ -112,21 +112,29 @@ namespace vk
image_view(VkDevice dev, VkImageViewCreateInfo create_info);
image_view(VkDevice dev, vk::image* resource,
VkFormat format = VK_FORMAT_UNDEFINED,
VkImageViewType view_type = VK_IMAGE_VIEW_TYPE_MAX_ENUM,
const VkComponentMapping& mapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A },
const VkImageSubresourceRange& range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
~image_view();
vk::image_view* as(VkFormat new_format);
u32 encoded_component_map() const;
vk::image* image() const;
image_view(const image_view&) = delete;
image_view(image_view&&) = delete;
VkFormat format() const { return info.format; }
private:
std::unordered_map<VkFormat, std::unique_ptr<vk::image_view>> m_subviews;
VkDevice m_device;
vk::image* m_resource = nullptr;
vk::image_view* m_root_view = nullptr;
void create_impl();
void set_debug_name(std::string_view name);
@ -141,9 +149,18 @@ namespace vk
public:
using image::image;
virtual image_view* get_view(const rsx::texture_channel_remap_t& remap,
virtual image_view* get_view(
VkFormat format,
const rsx::texture_channel_remap_t& remap,
VkImageAspectFlags mask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT);
image_view* get_view(
const rsx::texture_channel_remap_t& remap,
VkImageAspectFlags mask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT)
{
return get_view(info.format, remap, mask);
}
void set_native_component_layout(VkComponentMapping new_layout);
};
}