mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-31 12:31:45 +01:00
rsx: Implement GPU acceleration for rotated images
This commit is contained in:
parent
5260f4b47d
commit
bb65e45614
@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
|
||||
@ -673,6 +673,16 @@ struct area_base
|
||||
return{ x1, y1, x2 - x1, y2 - y1 };
|
||||
}
|
||||
|
||||
constexpr T width() const
|
||||
{
|
||||
return (x1 < x2) ? (x2 - x1) : (x1 - x2);
|
||||
}
|
||||
|
||||
constexpr T height() const
|
||||
{
|
||||
return (y1 < y2) ? (y2 - y1) : (y1 - y2);
|
||||
}
|
||||
|
||||
void flip_vertical()
|
||||
{
|
||||
T _y = y1; y1 = y2; y2 = _y;
|
||||
@ -693,6 +703,11 @@ struct area_base
|
||||
return{ x2, y1, x1, y2 };
|
||||
}
|
||||
|
||||
constexpr bool is_flipped() const
|
||||
{
|
||||
return (x1 > x2 || y1 > y2);
|
||||
}
|
||||
|
||||
constexpr bool operator == (const area_base& rhs) const
|
||||
{
|
||||
return x1 == rhs.x1 && x2 == rhs.x2 && y1 == rhs.y1 && y2 == rhs.y2;
|
||||
|
@ -40,6 +40,9 @@ namespace rsx
|
||||
bool dst_is_typeless = false;
|
||||
bool src_is_depth = false;
|
||||
bool dst_is_depth = false;
|
||||
bool flip_vertical = false;
|
||||
bool flip_horizontal = false;
|
||||
|
||||
u32 src_gcm_format = 0;
|
||||
u32 dst_gcm_format = 0;
|
||||
u32 src_native_format_override = 0;
|
||||
|
@ -2206,29 +2206,21 @@ namespace rsx
|
||||
// TODO: Verify correct behavior
|
||||
bool src_is_render_target = false;
|
||||
bool dst_is_render_target = false;
|
||||
bool dst_is_argb8 = (dst.format == rsx::blit_engine::transfer_destination_format::a8r8g8b8);
|
||||
bool src_is_argb8 = (src.format == rsx::blit_engine::transfer_source_format::a8r8g8b8);
|
||||
const bool dst_is_argb8 = (dst.format == rsx::blit_engine::transfer_destination_format::a8r8g8b8);
|
||||
const bool src_is_argb8 = (src.format == rsx::blit_engine::transfer_source_format::a8r8g8b8);
|
||||
const u8 src_bpp = src_is_argb8 ? 4 : 2;
|
||||
const u8 dst_bpp = dst_is_argb8 ? 4 : 2;
|
||||
|
||||
typeless_xfer typeless_info = {};
|
||||
image_resource_type vram_texture = 0;
|
||||
image_resource_type dest_texture = 0;
|
||||
|
||||
const u32 src_address = (u32)((u64)src.pixels - (u64)vm::base(0));
|
||||
const u32 dst_address = (u32)((u64)dst.pixels - (u64)vm::base(0));
|
||||
u32 src_address = (u32)((u64)src.pixels - (u64)vm::base(0));
|
||||
|
||||
const f32 scale_x = fabsf(dst.scale_x);
|
||||
const f32 scale_y = fabsf(dst.scale_y);
|
||||
|
||||
if (dst.scale_y < 0.f)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
if (dst.scale_x < 0.f)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// Offset in x and y for src is 0 (it is already accounted for when getting pixels_src)
|
||||
// Reproject final clip onto source...
|
||||
u16 src_w = (u16)((f32)dst.clip_width / scale_x);
|
||||
@ -2237,6 +2229,18 @@ namespace rsx
|
||||
u16 dst_w = dst.clip_width;
|
||||
u16 dst_h = dst.clip_height;
|
||||
|
||||
if (dst.scale_y < 0.f)
|
||||
{
|
||||
typeless_info.flip_vertical = true;
|
||||
src_address -= (src.pitch * (src_h - 1));
|
||||
}
|
||||
|
||||
if (dst.scale_x < 0.f)
|
||||
{
|
||||
typeless_info.flip_horizontal = true;
|
||||
src_address += (src.width - src_w) * src_bpp;
|
||||
}
|
||||
|
||||
auto rtt_lookup = [&m_rtts, &cmd](u32 address, u32 width, u32 height, u32 pitch, bool allow_clipped) -> typename surface_store_type::surface_overlap_info
|
||||
{
|
||||
const auto list = m_rtts.get_merged_texture_memory_region(cmd, address, width, height, pitch);
|
||||
@ -2269,8 +2273,7 @@ namespace rsx
|
||||
{
|
||||
if (dst.scale_x > 0.f && dst.scale_y > 0.f)
|
||||
{
|
||||
const u8 bpp = dst_is_argb8 ? 4 : 2;
|
||||
const u32 memcpy_bytes_length = dst.clip_width * bpp * dst.clip_height;
|
||||
const u32 memcpy_bytes_length = dst.clip_width * dst_bpp * dst.clip_height;
|
||||
|
||||
std::lock_guard lock(m_cache_mutex);
|
||||
invalidate_range_impl_base(cmd, address_range::start_length(src_address, memcpy_bytes_length), invalidation_cause::read, std::forward<Args>(extras)...);
|
||||
@ -2291,14 +2294,13 @@ namespace rsx
|
||||
src_subres.surface->read_barrier(cmd);
|
||||
|
||||
const auto surf = src_subres.surface;
|
||||
auto src_bpp = surf->get_native_pitch() / surf->get_surface_width();
|
||||
auto expected_bpp = src_is_argb8 ? 4 : 2;
|
||||
if (src_bpp != expected_bpp)
|
||||
auto bpp = surf->get_native_pitch() / surf->get_surface_width();
|
||||
if (bpp != src_bpp)
|
||||
{
|
||||
//Enable type scaling in src
|
||||
typeless_info.src_is_typeless = true;
|
||||
typeless_info.src_is_depth = src_subres.is_depth;
|
||||
typeless_info.src_scaling_hint = (f32)src_bpp / expected_bpp;
|
||||
typeless_info.src_scaling_hint = (f32)bpp / src_bpp;
|
||||
typeless_info.src_gcm_format = src_is_argb8 ? CELL_GCM_TEXTURE_A8R8G8B8 : CELL_GCM_TEXTURE_R5G6B5;
|
||||
|
||||
src_w = (u16)(src_w / typeless_info.src_scaling_hint);
|
||||
@ -2316,14 +2318,13 @@ namespace rsx
|
||||
// Full barrier is required in case of partial transfers
|
||||
dst_subres.surface->read_barrier(cmd);
|
||||
|
||||
auto dst_bpp = dst_subres.surface->get_native_pitch() / dst_subres.surface->get_surface_width();
|
||||
auto expected_bpp = dst_is_argb8 ? 4 : 2;
|
||||
if (dst_bpp != expected_bpp)
|
||||
auto bpp = dst_subres.surface->get_native_pitch() / dst_subres.surface->get_surface_width();
|
||||
if (bpp != dst_bpp)
|
||||
{
|
||||
//Enable type scaling in dst
|
||||
typeless_info.dst_is_typeless = true;
|
||||
typeless_info.dst_is_depth = dst_subres.is_depth;
|
||||
typeless_info.dst_scaling_hint = (f32)dst_bpp / expected_bpp;
|
||||
typeless_info.dst_scaling_hint = (f32)bpp / dst_bpp;
|
||||
typeless_info.dst_gcm_format = dst_is_argb8 ? CELL_GCM_TEXTURE_A8R8G8B8 : CELL_GCM_TEXTURE_R5G6B5;
|
||||
|
||||
dst_w = (u16)(dst_w / typeless_info.dst_scaling_hint);
|
||||
@ -2342,7 +2343,7 @@ namespace rsx
|
||||
areai src_area = { 0, 0, src_w, src_h };
|
||||
areai dst_area = { 0, 0, dst_w, dst_h };
|
||||
|
||||
size2i dst_dimensions = { dst.pitch / (dst_is_argb8 ? 4 : 2), dst.height };
|
||||
size2i dst_dimensions = { dst.pitch / dst_bpp, dst.height };
|
||||
if (src_is_render_target)
|
||||
{
|
||||
if (dst_dimensions.width == src_subres.surface->get_surface_width())
|
||||
@ -2395,10 +2396,9 @@ namespace rsx
|
||||
|
||||
if (const u32 address_offset = dst_address - this_address)
|
||||
{
|
||||
const u16 bpp = dst_is_argb8 ? 4 : 2;
|
||||
const u16 offset_y = address_offset / dst.pitch;
|
||||
const u16 offset_x = address_offset % dst.pitch;
|
||||
const u16 offset_x_in_block = offset_x / bpp;
|
||||
const u16 offset_x_in_block = offset_x / dst_bpp;
|
||||
|
||||
dst_area.x1 += offset_x_in_block;
|
||||
dst_area.x2 += offset_x_in_block;
|
||||
@ -2513,10 +2513,9 @@ namespace rsx
|
||||
|
||||
if (const u32 address_offset = src_address - this_address)
|
||||
{
|
||||
const u16 bpp = src_is_argb8 ? 4 : 2;
|
||||
const u16 offset_y = address_offset / src.pitch;
|
||||
const u16 offset_x = address_offset % src.pitch;
|
||||
const u16 offset_x_in_block = offset_x / bpp;
|
||||
const u16 offset_x_in_block = offset_x / src_bpp;
|
||||
|
||||
src_area.x1 += offset_x_in_block;
|
||||
src_area.x2 += offset_x_in_block;
|
||||
@ -2542,7 +2541,7 @@ namespace rsx
|
||||
const auto rsx_range = address_range::start_length(src_address, src.pitch * src.slice_h);
|
||||
invalidate_range_impl_base(cmd, rsx_range, invalidation_cause::read, std::forward<Args>(extras)...);
|
||||
|
||||
const u16 _width = src_is_argb8 ? src.pitch >> 2 : src.pitch >> 1;
|
||||
const u16 _width = src.pitch / src_bpp;
|
||||
std::vector<rsx_subresource_layout> subresource_layout;
|
||||
rsx_subresource_layout subres = {};
|
||||
subres.width_in_block = _width;
|
||||
@ -2650,7 +2649,7 @@ namespace rsx
|
||||
}
|
||||
else
|
||||
{
|
||||
const u16 pitch_in_block = dst_is_argb8 ? dst.pitch >> 2 : dst.pitch >> 1;
|
||||
const u16 pitch_in_block = dst.pitch / dst_bpp;
|
||||
std::vector<rsx_subresource_layout> subresource_layout;
|
||||
rsx_subresource_layout subres = {};
|
||||
subres.width_in_block = dst_dimensions.width;
|
||||
@ -2680,7 +2679,7 @@ namespace rsx
|
||||
|
||||
if (dst.clip_height == 1)
|
||||
{
|
||||
mem_length = dst.clip_width * (dst_is_argb8 ? 4 : 2);
|
||||
mem_length = dst.clip_width * dst_bpp;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -434,6 +434,16 @@ namespace gl
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, blit_dst.id());
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, dst_id, 0);
|
||||
|
||||
if (xfer_info.flip_horizontal)
|
||||
{
|
||||
src_rect.flip_horizontal();
|
||||
}
|
||||
|
||||
if (xfer_info.flip_vertical)
|
||||
{
|
||||
src_rect.flip_vertical();
|
||||
}
|
||||
|
||||
glBlitFramebuffer(src_rect.x1, src_rect.y1, src_rect.x2, src_rect.y2,
|
||||
dst_rect.x1, dst_rect.y1, dst_rect.x2, dst_rect.y2,
|
||||
(GLbitfield)target, (GLenum)interp);
|
||||
|
@ -3366,7 +3366,7 @@ void VKGSRender::flip(int buffer)
|
||||
}
|
||||
|
||||
vk::copy_scaled_image(*m_current_command_buffer, image_to_flip->value, target_image, image_to_flip->current_layout, target_layout,
|
||||
0, 0, buffer_width, buffer_height, aspect_ratio.x, aspect_ratio.y, aspect_ratio.width, aspect_ratio.height, 1, VK_IMAGE_ASPECT_COLOR_BIT, false);
|
||||
{ 0, 0, (s32)buffer_width, (s32)buffer_height }, aspect_ratio, 1, VK_IMAGE_ASPECT_COLOR_BIT, false);
|
||||
|
||||
if (target_layout != present_layout)
|
||||
{
|
||||
|
@ -155,8 +155,8 @@ namespace vk
|
||||
VkImageAspectFlags src_transfer_mask = 0xFF, VkImageAspectFlags dst_transfer_mask = 0xFF);
|
||||
|
||||
void copy_scaled_image(VkCommandBuffer cmd, VkImage src, VkImage dst, VkImageLayout srcLayout, VkImageLayout dstLayout,
|
||||
u32 src_x_offset, u32 src_y_offset, u32 src_width, u32 src_height, u32 dst_x_offset, u32 dst_y_offset, u32 dst_width, u32 dst_height, u32 mipmaps,
|
||||
VkImageAspectFlags aspect, bool compatible_formats, VkFilter filter = VK_FILTER_LINEAR, VkFormat src_format = VK_FORMAT_UNDEFINED, VkFormat dst_format = VK_FORMAT_UNDEFINED);
|
||||
const areai& src_rect, const areai& dst_rect, u32 mipmaps, VkImageAspectFlags aspect, bool compatible_formats,
|
||||
VkFilter filter = VK_FILTER_LINEAR, VkFormat src_format = VK_FORMAT_UNDEFINED, VkFormat dst_format = VK_FORMAT_UNDEFINED);
|
||||
|
||||
std::pair<VkFormat, VkComponentMapping> get_compatible_surface_format(rsx::surface_color_format color_format);
|
||||
size_t get_render_pass_location(VkFormat color_surface_format, VkFormat depth_stencil_format, u8 color_surface_count);
|
||||
|
@ -252,8 +252,7 @@ namespace vk
|
||||
void copy_scaled_image(VkCommandBuffer cmd,
|
||||
VkImage src, VkImage dst,
|
||||
VkImageLayout srcLayout, VkImageLayout dstLayout,
|
||||
u32 src_x_offset, u32 src_y_offset, u32 src_width, u32 src_height,
|
||||
u32 dst_x_offset, u32 dst_y_offset, u32 dst_width, u32 dst_height,
|
||||
const areai& src_rect, const areai& dst_rect,
|
||||
u32 mipmaps, VkImageAspectFlags aspect, bool compatible_formats,
|
||||
VkFilter filter, VkFormat src_format, VkFormat dst_format)
|
||||
{
|
||||
@ -275,14 +274,15 @@ namespace vk
|
||||
if (dstLayout != preferred_dst_format && src != dst)
|
||||
change_image_layout(cmd, dst, dstLayout, preferred_dst_format, vk::get_image_subresource_range(0, 0, 1, 1, aspect));
|
||||
|
||||
if (compatible_formats && src_width == dst_width && src_height == dst_height)
|
||||
if (compatible_formats && !src_rect.is_flipped() && !dst_rect.is_flipped() &&
|
||||
src_rect.width() == dst_rect.width() && src_rect.height() == dst_rect.height())
|
||||
{
|
||||
VkImageCopy copy_rgn;
|
||||
copy_rgn.srcOffset = { (int32_t)src_x_offset, (int32_t)src_y_offset, 0 };
|
||||
copy_rgn.dstOffset = { (int32_t)dst_x_offset, (int32_t)dst_y_offset, 0 };
|
||||
copy_rgn.srcOffset = { src_rect.x1, src_rect.y1, 0 };
|
||||
copy_rgn.dstOffset = { dst_rect.x1, dst_rect.y1, 0 };
|
||||
copy_rgn.dstSubresource = { (VkImageAspectFlags)aspect, 0, 0, 1 };
|
||||
copy_rgn.srcSubresource = { (VkImageAspectFlags)aspect, 0, 0, 1 };
|
||||
copy_rgn.extent = { src_width, src_height, 1 };
|
||||
copy_rgn.extent = { (u32)src_rect.width(), (u32)src_rect.height(), 1 };
|
||||
|
||||
vkCmdCopyImage(cmd, src, preferred_src_format, dst, preferred_dst_format, 1, ©_rgn);
|
||||
}
|
||||
@ -291,18 +291,19 @@ namespace vk
|
||||
//Most depth/stencil formats cannot be scaled using hw blit
|
||||
if (src_format == VK_FORMAT_UNDEFINED)
|
||||
{
|
||||
LOG_ERROR(RSX, "Could not blit depth/stencil image. src_fmt=0x%x, src=%dx%d, dst=%dx%d",
|
||||
(u32)src_format, src_width, src_height, dst_width, dst_height);
|
||||
LOG_ERROR(RSX, "Could not blit depth/stencil image. src_fmt=0x%x", (u32)src_format);
|
||||
}
|
||||
else
|
||||
{
|
||||
verify(HERE), !dst_rect.is_flipped();
|
||||
|
||||
auto stretch_image_typeless_unsafe = [&cmd, preferred_src_format, preferred_dst_format, filter](VkImage src, VkImage dst, VkImage typeless,
|
||||
const areai& src_rect, const areai& dst_rect, VkImageAspectFlags aspect, VkImageAspectFlags transfer_flags = 0xFF)
|
||||
{
|
||||
const u32 src_w = u32(src_rect.x2 - src_rect.x1);
|
||||
const u32 src_h = u32(src_rect.y2 - src_rect.y1);
|
||||
const u32 dst_w = u32(dst_rect.x2 - dst_rect.x1);
|
||||
const u32 dst_h = u32(dst_rect.y2 - dst_rect.y1);
|
||||
const auto src_w = src_rect.width();
|
||||
const auto src_h = src_rect.height();
|
||||
const auto dst_w = dst_rect.width();
|
||||
const auto dst_h = dst_rect.height();
|
||||
|
||||
// Drivers are not very accepting of aspect COLOR -> aspect DEPTH or aspect STENCIL separately
|
||||
// However, this works okay for D24S8 (nvidia-only format)
|
||||
@ -310,31 +311,31 @@ namespace vk
|
||||
|
||||
//1. Copy unscaled to typeless surface
|
||||
copy_image(cmd, src, typeless, preferred_src_format, VK_IMAGE_LAYOUT_GENERAL,
|
||||
src_rect, { 0, 0, (s32)src_w, (s32)src_h }, 1, aspect, VK_IMAGE_ASPECT_COLOR_BIT, transfer_flags, 0xFF);
|
||||
src_rect, { 0, 0, src_w, src_h }, 1, aspect, VK_IMAGE_ASPECT_COLOR_BIT, transfer_flags, 0xFF);
|
||||
|
||||
//2. Blit typeless surface to self
|
||||
copy_scaled_image(cmd, typeless, typeless, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
|
||||
0, 0, src_w, src_h, 0, src_h, dst_w, dst_h, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT, filter);
|
||||
{ 0, 0, src_w, src_h }, { 0, src_h, dst_w, (src_h + dst_h) }, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT, filter);
|
||||
|
||||
//3. Copy back the aspect bits
|
||||
copy_image(cmd, typeless, dst, VK_IMAGE_LAYOUT_GENERAL, preferred_dst_format,
|
||||
{0, (s32)src_h, (s32)dst_w, s32(src_h + dst_h) }, dst_rect, 1, VK_IMAGE_ASPECT_COLOR_BIT, aspect, 0xFF, transfer_flags);
|
||||
{0, src_h, dst_w, (src_h + dst_h) }, dst_rect, 1, VK_IMAGE_ASPECT_COLOR_BIT, aspect, 0xFF, transfer_flags);
|
||||
};
|
||||
|
||||
auto stretch_image_typeless_safe = [&cmd, preferred_src_format, preferred_dst_format, filter](VkImage src, VkImage dst, VkImage typeless,
|
||||
const areai& src_rect, const areai& dst_rect, VkImageAspectFlags aspect, VkImageAspectFlags transfer_flags = 0xFF)
|
||||
{
|
||||
const u32 src_w = u32(src_rect.x2 - src_rect.x1);
|
||||
const u32 src_h = u32(src_rect.y2 - src_rect.y1);
|
||||
const u32 dst_w = u32(dst_rect.x2 - dst_rect.x1);
|
||||
const u32 dst_h = u32(dst_rect.y2 - dst_rect.y1);
|
||||
const auto src_w = src_rect.width();
|
||||
const auto src_h = src_rect.height();
|
||||
const auto dst_w = dst_rect.width();
|
||||
const auto dst_h = dst_rect.height();
|
||||
|
||||
auto scratch_buf = vk::get_scratch_buffer();
|
||||
|
||||
//1. Copy unscaled to typeless surface
|
||||
VkBufferImageCopy info{};
|
||||
info.imageOffset = { src_rect.x1, src_rect.y1, 0 };
|
||||
info.imageExtent = { src_w, src_h, 1 };
|
||||
info.imageOffset = { std::min(src_rect.x1, src_rect.x2), std::min(src_rect.y1, src_rect.y2), 0 };
|
||||
info.imageExtent = { (u32)src_w, (u32)src_h, 1 };
|
||||
info.imageSubresource = { aspect & transfer_flags, 0, 0, 1 };
|
||||
|
||||
vkCmdCopyImageToBuffer(cmd, src, preferred_src_format, scratch_buf->value, 1, &info);
|
||||
@ -343,13 +344,17 @@ namespace vk
|
||||
info.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
|
||||
vkCmdCopyBufferToImage(cmd, scratch_buf->value, typeless, VK_IMAGE_LAYOUT_GENERAL, 1, &info);
|
||||
|
||||
//2. Blit typeless surface to self
|
||||
//2. Blit typeless surface to self and apply transform if necessary
|
||||
areai src_rect2 = { 0, 0, src_w, src_h };
|
||||
if (src_rect.x1 > src_rect.x2) src_rect2.flip_horizontal();
|
||||
if (src_rect.y1 > src_rect.y2) src_rect2.flip_vertical();
|
||||
|
||||
copy_scaled_image(cmd, typeless, typeless, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
|
||||
0, 0, src_w, src_h, 0, src_h, dst_w, dst_h, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT, filter);
|
||||
src_rect2, { 0, src_h, dst_w, (src_h + dst_h) }, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT, filter);
|
||||
|
||||
//3. Copy back the aspect bits
|
||||
info.imageExtent = { dst_w, dst_h, 1 };
|
||||
info.imageOffset = { 0, (s32)src_h, 0 };
|
||||
info.imageExtent = { (u32)dst_w, (u32)dst_h, 1 };
|
||||
info.imageOffset = { 0, src_h, 0 };
|
||||
|
||||
vkCmdCopyImageToBuffer(cmd, typeless, VK_IMAGE_LAYOUT_GENERAL, scratch_buf->value, 1, &info);
|
||||
insert_buffer_memory_barrier(cmd, scratch_buf->value, 0, VK_WHOLE_SIZE, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
|
||||
@ -359,10 +364,8 @@ namespace vk
|
||||
vkCmdCopyBufferToImage(cmd, scratch_buf->value, dst, preferred_dst_format, 1, &info);
|
||||
};
|
||||
|
||||
const areai src_rect = { (s32)src_x_offset, (s32)src_y_offset, s32(src_x_offset + src_width), s32(src_y_offset + src_height) };
|
||||
const areai dst_rect = { (s32)dst_x_offset, (s32)dst_y_offset, s32(dst_x_offset + dst_width), s32(dst_y_offset + dst_height) };
|
||||
const u32 typeless_w = dst_width;
|
||||
const u32 typeless_h = src_height + dst_height;
|
||||
const u32 typeless_w = dst_rect.width();
|
||||
const u32 typeless_h = src_rect.height() + dst_rect.height();
|
||||
|
||||
switch (src_format)
|
||||
{
|
||||
@ -404,10 +407,10 @@ namespace vk
|
||||
else
|
||||
{
|
||||
VkImageBlit rgn = {};
|
||||
rgn.srcOffsets[0] = { (int32_t)src_x_offset, (int32_t)src_y_offset, 0 };
|
||||
rgn.srcOffsets[1] = { (int32_t)(src_width + src_x_offset), (int32_t)(src_height + src_y_offset), 1 };
|
||||
rgn.dstOffsets[0] = { (int32_t)dst_x_offset, (int32_t)dst_y_offset, 0 };
|
||||
rgn.dstOffsets[1] = { (int32_t)(dst_width + dst_x_offset), (int32_t)(dst_height + dst_y_offset), 1 };
|
||||
rgn.srcOffsets[0] = { src_rect.x1, src_rect.y1, 0 };
|
||||
rgn.srcOffsets[1] = { src_rect.x2, src_rect.y2, 1 };
|
||||
rgn.dstOffsets[0] = { dst_rect.x1, dst_rect.y1, 0 };
|
||||
rgn.dstOffsets[1] = { dst_rect.x2, dst_rect.y2, 1 };
|
||||
rgn.dstSubresource = a_dst;
|
||||
rgn.srcSubresource = a_src;
|
||||
|
||||
@ -638,13 +641,18 @@ namespace vk
|
||||
return;
|
||||
}
|
||||
|
||||
const auto src_width = src_area.x2 - src_area.x1;
|
||||
const auto src_height = src_area.y2 - src_area.y1;
|
||||
const auto dst_width = dst_area.x2 - dst_area.x1;
|
||||
const auto dst_height = dst_area.y2 - dst_area.y1;
|
||||
if (xfer_info.flip_horizontal)
|
||||
{
|
||||
src_area.flip_horizontal();
|
||||
}
|
||||
|
||||
copy_scaled_image(cmd, real_src->value, real_dst->value, real_src->current_layout, real_dst->current_layout, src_area.x1, src_area.y1, src_width, src_height,
|
||||
dst_area.x1, dst_area.y1, dst_width, dst_height, 1, dst_aspect, real_src->info.format == real_dst->info.format,
|
||||
if (xfer_info.flip_vertical)
|
||||
{
|
||||
src_area.flip_vertical();
|
||||
}
|
||||
|
||||
copy_scaled_image(cmd, real_src->value, real_dst->value, real_src->current_layout, real_dst->current_layout,
|
||||
src_area, dst_area, 1, dst_aspect, real_src->info.format == real_dst->info.format,
|
||||
interpolate ? VK_FILTER_LINEAR : VK_FILTER_NEAREST, real_src->info.format, real_dst->info.format);
|
||||
|
||||
if (real_dst != dst)
|
||||
|
@ -235,8 +235,8 @@ namespace vk
|
||||
const auto filter = (aspect_flag == VK_IMAGE_ASPECT_COLOR_BIT) ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
|
||||
|
||||
vk::copy_scaled_image(cmd, vram_texture->value, target->value, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, target->current_layout,
|
||||
0, 0, vram_texture->width(), vram_texture->height(), 0, 0, transfer_width, transfer_height, 1, aspect_flag, true, filter,
|
||||
vram_texture->info.format, target->info.format);
|
||||
{ 0, 0, (s32)vram_texture->width(), (s32)vram_texture->height() }, { 0, 0, (s32)transfer_width, (s32)transfer_height },
|
||||
1, aspect_flag, true, filter, vram_texture->info.format, target->info.format);
|
||||
}
|
||||
}
|
||||
|
||||
@ -536,7 +536,7 @@ namespace vk
|
||||
{
|
||||
verify(HERE), section.dst_z == 0;
|
||||
|
||||
u32 dst_x = section.dst_x, dst_y = section.dst_y;
|
||||
u16 dst_x = section.dst_x, dst_y = section.dst_y;
|
||||
vk::image* _dst;
|
||||
|
||||
if (LIKELY(section.src->info.format == dst->info.format))
|
||||
@ -552,8 +552,8 @@ namespace vk
|
||||
if (section.xform == surface_transform::identity)
|
||||
{
|
||||
vk::copy_scaled_image(cmd, section.src->value, _dst->value, section.src->current_layout, _dst->current_layout,
|
||||
section.src_x, section.src_y, section.src_w, section.src_h,
|
||||
section.dst_x, section.dst_y, section.dst_w, section.dst_h,
|
||||
coordi{ { section.src_x, section.src_y }, { section.src_w, section.src_h } },
|
||||
coordi{ { section.dst_x, section.dst_y }, { section.dst_w, section.dst_h } },
|
||||
1, src_aspect, section.src->info.format == _dst->info.format,
|
||||
VK_FILTER_NEAREST, section.src->info.format, _dst->info.format);
|
||||
}
|
||||
@ -593,8 +593,8 @@ namespace vk
|
||||
}
|
||||
|
||||
vk::copy_scaled_image(cmd, tmp->value, _dst->value, tmp->current_layout, _dst->current_layout,
|
||||
0, 0, section.src_w, section.src_h,
|
||||
dst_x, dst_y, section.dst_w, section.dst_h,
|
||||
areai{ 0, 0, (s32)section.src_w, (s32)section.src_h },
|
||||
coordi{ {dst_x, dst_y}, {section.dst_w, section.dst_h} },
|
||||
1, src_aspect, section.src->info.format == _dst->info.format,
|
||||
VK_FILTER_NEAREST, tmp->info.format, _dst->info.format);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user