mirror of
https://github.com/ARMSX2/ARMSX3.git
synced 2026-08-24 16:58:52 -07:00
rsx/vk: Implement support for multi-layer, multi-level and explicit mip/layer image transfers
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+392
-269
File diff suppressed because it is too large
Load Diff
@@ -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]]
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user