rsx/vk: Implement support for multi-layer, multi-level and explicit mip/layer image transfers

This commit is contained in:
kd-11
2026-08-18 13:47:28 +03:00
committed by kd-11
parent 6892ee4c2e
commit a88331bb22
9 changed files with 455 additions and 287 deletions
+34
View File
@@ -305,6 +305,40 @@ namespace rsx
bool edge_clamped;
};
struct image_copy_subresource_layers
{
u8 src_mip_level = 0;
u8 dst_mip_level = 0;
u8 mipmap_count = 1;
u8 src_layer = 0;
u8 dst_layer = 0;
u8 layer_count = 1;
image_copy_subresource_layers without_src() const
{
return {
.src_mip_level = 0,
.dst_mip_level = dst_mip_level,
.mipmap_count = 1,
.src_layer = 0,
.dst_layer = dst_layer,
.layer_count = 1
};
}
image_copy_subresource_layers without_dst() const
{
return {
.src_mip_level = src_mip_level,
.dst_mip_level = 0,
.mipmap_count = 1,
.src_layer = src_layer,
.dst_layer = 0,
.layer_count = 1
};
}
};
/**
* Get size to store texture in a linear fashion.
* Storage is assumed to use a rowPitchAlignment boundary for every row of texture.
+7 -1
View File
@@ -34,7 +34,13 @@ namespace gl
void destroy();
void scale_image(gl::command_context& cmd, const texture* src, texture* dst, areai src_rect, areai dst_rect, bool linear_interpolation,
void scale_image(
gl::command_context& cmd,
const texture* src,
texture* dst,
areai src_rect,
areai dst_rect,
bool linear_interpolation,
const rsx::typeless_xfer& xfer_info);
void copy_image(gl::command_context& cmd, const texture* src, const texture* dst, int src_level, int dst_level, const position3i& src_offset, const position3i& dst_offset, const size3i& size) const;
+13 -8
View File
@@ -95,16 +95,21 @@ namespace vk
void copy_buffer_to_image(const vk::command_buffer& cmd, const vk::buffer* src, const vk::image* dst, const VkBufferImageCopy& region);
u64 calculate_working_buffer_size(u64 base_size, VkImageAspectFlags aspect);
void copy_image_typeless(const command_buffer &cmd, image *src, image *dst, const areai& src_rect, const areai& dst_rect,
u32 mipmaps, VkImageAspectFlags src_transfer_mask = 0xFF, VkImageAspectFlags dst_transfer_mask = 0xFF);
void copy_image(const vk::command_buffer& cmd, vk::image* src, vk::image* dst,
const areai& src_rect, const areai& dst_rect, u32 mipmaps,
void copy_image_typeless(const command_buffer &cmd, image *src, image *dst,
const areai& src_rect, const areai& dst_rect,
const rsx::image_copy_subresource_layers& mip_layers = {},
VkImageAspectFlags src_transfer_mask = 0xFF, VkImageAspectFlags dst_transfer_mask = 0xFF);
void copy_scaled_image(const vk::command_buffer& cmd, vk::image* src, vk::image* dst,
const areai& src_rect, const areai& dst_rect, u32 mipmaps,
bool compatible_formats, VkFilter filter = VK_FILTER_LINEAR);
void copy_image(const vk::command_buffer& cmd, vk::image* src, vk::image* dst,
const areai& src_rect, const areai& dst_rect,
const rsx::image_copy_subresource_layers& mip_layers = {},
VkImageAspectFlags src_transfer_mask = 0xFF, VkImageAspectFlags dst_transfer_mask = 0xFF);
void copy_scaled_image(const vk::command_buffer& cmd,
vk::image* src, vk::image* dst,
const areai& src_rect, const areai& dst_rect,
const rsx::image_copy_subresource_layers& mip_layers = {},
bool compatible_formats = false, VkFilter filter = VK_FILTER_LINEAR);
std::pair<VkFormat, VkComponentMapping> get_compatible_surface_format(rsx::surface_color_format color_format);
+3 -3
View File
@@ -407,11 +407,11 @@ vk::viewable_image* VKGSRender::get_present_source(/* inout */ vk::present_surfa
if (vk::formats_are_bitcast_compatible(dst_img.get(), image_to_flip))
{
vk::copy_image(*m_current_command_buffer, image_to_flip, dst_img.get(), src_rect, dst_rect, 1);
vk::copy_image(*m_current_command_buffer, image_to_flip, dst_img.get(), src_rect, dst_rect);
}
else
{
vk::copy_image_typeless(*m_current_command_buffer, image_to_flip, dst_img.get(), src_rect, dst_rect, 1);
vk::copy_image_typeless(*m_current_command_buffer, image_to_flip, dst_img.get(), src_rect, dst_rect);
}
image_to_flip = dst_img.get();
@@ -735,7 +735,7 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info)
image_to_flip->push_layout(*m_current_command_buffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
const areai rect = areai(0, 0, buffer_width, buffer_height);
vk::copy_image(*m_current_command_buffer, image_to_flip, m_overlay_recording_img.get(), rect, rect, 1);
vk::copy_image(*m_current_command_buffer, image_to_flip, m_overlay_recording_img.get(), rect, rect);
image_to_flip->pop_layout(*m_current_command_buffer);
m_overlay_recording_img->change_layout(*m_current_command_buffer, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+1 -1
View File
@@ -789,7 +789,7 @@ namespace vk
vk::copy_scaled_image(cmd, content, final_dst,
{ 0, 0, subres.width_in_block, subres.height_in_block },
{ 0, 0, static_cast<s32>(final_dst->width()), static_cast<s32>(final_dst->height()) },
1, true, aspect() == VK_IMAGE_ASPECT_COLOR_BIT ? VK_FILTER_LINEAR : VK_FILTER_NEAREST);
{}, true, aspect() == VK_IMAGE_ASPECT_COLOR_BIT ? VK_FILTER_LINEAR : VK_FILTER_NEAREST);
content->pop_layout(cmd);
}
+1 -1
View File
@@ -611,7 +611,7 @@ namespace vk
const areai dst_rect = { 0, 0, surface->get_surface_width<rsx::surface_metrics::samples, int>(), surface->get_surface_height<rsx::surface_metrics::samples, int>() };
auto scratch = vk::get_typeless_helper(source->format(), source->format_class(), dst_rect.x2, dst_rect.y2);
vk::copy_scaled_image(cmd, source, scratch, src_rect, dst_rect, 1, true, VK_FILTER_NEAREST);
vk::copy_scaled_image(cmd, source, scratch, src_rect, dst_rect, {}, true, VK_FILTER_NEAREST);
source = scratch;
}
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -496,7 +496,7 @@ namespace vk
// TODO: Handle level and layer offsets
const areai src_rect = coordi{{ src_x, src_y }, { src_w, src_h }};
const areai dst_rect = coordi{{ section.dst_x, section.dst_y }, { section.dst_w, section.dst_h }};
vk::copy_image_typeless(cmd, section.src, dst, src_rect, dst_rect, 1);
vk::copy_image_typeless(cmd, section.src, dst, src_rect, dst_rect);
continue;
}
@@ -505,7 +505,7 @@ namespace vk
const areai src_rect = coordi{{ src_x, src_y }, { src_w, src_h }};
const areai dst_rect = coordi{{ 0, 0 }, { convert_w, src_h }};
vk::copy_image_typeless(cmd, section.src, src_image, src_rect, dst_rect, 1);
vk::copy_image_typeless(cmd, section.src, src_image, src_rect, dst_rect);
src_image->change_layout(cmd, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
src_x = 0;
@@ -546,7 +546,7 @@ namespace vk
vk::copy_scaled_image(cmd, src_image, _dst,
coordi{ { src_x, src_y }, { src_w, src_h } },
coordi{ { dst_x, dst_y }, { section.dst_w, section.dst_h } },
1, src_image->format() == _dst->format(),
{}, src_image->format() == _dst->format(),
VK_FILTER_NEAREST);
if (_dst != dst) [[unlikely]]
+1 -1
View File
@@ -234,7 +234,7 @@ namespace vk
vk::copy_scaled_image(cmd, locked_resource, target,
{ 0, 0, static_cast<s32>(locked_resource->width()), static_cast<s32>(locked_resource->height()) },
{ 0, 0, static_cast<s32>(transfer_width), static_cast<s32>(transfer_height) },
1, true, filter);
{}, true, filter);
target->change_layout(cmd, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
}