mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 06:21:26 +12:00
rsx: Fixups for data cast operations via typeless transfer
This commit is contained in:
parent
f04a0a2bb6
commit
a5ed30a8c0
9 changed files with 207 additions and 86 deletions
|
@ -627,7 +627,8 @@ void gl::render_target::memory_barrier(gl::command_context& cmd, bool force_init
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Mem cast, generate typeless xfer info
|
// Mem cast, generate typeless xfer info
|
||||||
if (src_bpp != dst_bpp || aspect() != src_texture->aspect())
|
if (!formats_are_bitcast_compatible((GLenum)get_internal_format(), (GLenum)src_texture->get_internal_format()) ||
|
||||||
|
aspect() != src_texture->aspect())
|
||||||
{
|
{
|
||||||
typeless_info.src_is_typeless = true;
|
typeless_info.src_is_typeless = true;
|
||||||
typeless_info.src_context = rsx::texture_upload_context::framebuffer_storage;
|
typeless_info.src_context = rsx::texture_upload_context::framebuffer_storage;
|
||||||
|
|
|
@ -615,6 +615,97 @@ namespace gl
|
||||||
fill_texture(type, mipmaps, gcm_format, width, height, depth, subresources_layout, is_swizzled, gl_format, gl_type, data_upload_buf);
|
fill_texture(type, mipmaps, gcm_format, width, height, depth, subresources_layout, is_swizzled, gl_format, gl_type, data_upload_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 get_format_texel_width(GLenum format)
|
||||||
|
{
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case GL_R8:
|
||||||
|
return 1;
|
||||||
|
case GL_R32F:
|
||||||
|
case GL_RG16:
|
||||||
|
case GL_RG16F:
|
||||||
|
case GL_RGBA8:
|
||||||
|
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||||
|
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
||||||
|
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||||
|
return 4;
|
||||||
|
case GL_R16:
|
||||||
|
case GL_RG8:
|
||||||
|
case GL_RGB565:
|
||||||
|
return 2;
|
||||||
|
case GL_RGBA16F:
|
||||||
|
return 8;
|
||||||
|
case GL_RGBA32F:
|
||||||
|
return 16;
|
||||||
|
case GL_DEPTH_COMPONENT16:
|
||||||
|
return 2;
|
||||||
|
case GL_DEPTH24_STENCIL8:
|
||||||
|
case GL_DEPTH32F_STENCIL8:
|
||||||
|
return 4;
|
||||||
|
default:
|
||||||
|
fmt::throw_exception("Unexpected internal format 0x%X" HERE, (u32)format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<bool, u32> get_format_convert_flags(GLenum format)
|
||||||
|
{
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case GL_R8:
|
||||||
|
case GL_RG8:
|
||||||
|
case GL_RGBA8:
|
||||||
|
return { false, 1 };
|
||||||
|
case GL_R16:
|
||||||
|
case GL_RG16:
|
||||||
|
case GL_RG16F:
|
||||||
|
case GL_RGB565:
|
||||||
|
case GL_RGBA16F:
|
||||||
|
return { true, 2 };
|
||||||
|
case GL_R32F:
|
||||||
|
case GL_RGBA32F:
|
||||||
|
return { true, 4 };
|
||||||
|
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||||
|
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
||||||
|
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||||
|
return { false, 4 };
|
||||||
|
case GL_DEPTH_COMPONENT16:
|
||||||
|
return { true, 2 };
|
||||||
|
case GL_DEPTH24_STENCIL8:
|
||||||
|
case GL_DEPTH32F_STENCIL8:
|
||||||
|
return { true, 4 };
|
||||||
|
default:
|
||||||
|
fmt::throw_exception("Unexpected internal format 0x%X" HERE, (u32)format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool formats_are_bitcast_compatible(GLenum format1, GLenum format2)
|
||||||
|
{
|
||||||
|
if (LIKELY(format1 == format2))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Formats are compatible if the following conditions are met:
|
||||||
|
// 1. Texel sizes must match
|
||||||
|
// 2. Both formats require no transforms (basic memcpy) or...
|
||||||
|
// 3. Both formats have the same transform (e.g RG16_UNORM to RG16_SFLOAT, both are down and uploaded with a 2-byte byteswap)
|
||||||
|
|
||||||
|
if (get_format_texel_width(format1) != get_format_texel_width(format2))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto transform_a = get_format_convert_flags(format1);
|
||||||
|
const auto transform_b = get_format_convert_flags(format2);
|
||||||
|
|
||||||
|
if (transform_a.first == transform_b.first)
|
||||||
|
{
|
||||||
|
return !transform_a.first || (transform_a.second == transform_b.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void copy_typeless(texture * dst, const texture * src)
|
void copy_typeless(texture * dst, const texture * src)
|
||||||
{
|
{
|
||||||
GLsizeiptr src_mem = src->width() * src->height();
|
GLsizeiptr src_mem = src->width() * src->height();
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace gl
|
||||||
|
|
||||||
viewable_image* create_texture(u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps, rsx::texture_dimension_extended type);
|
viewable_image* create_texture(u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps, rsx::texture_dimension_extended type);
|
||||||
|
|
||||||
|
bool formats_are_bitcast_compatible(GLenum format1, GLenum format2);
|
||||||
void copy_typeless(texture* dst, const texture* src);
|
void copy_typeless(texture* dst, const texture* src);
|
||||||
/**
|
/**
|
||||||
* is_swizzled - determines whether input bytes are in morton order
|
* is_swizzled - determines whether input bytes are in morton order
|
||||||
|
|
|
@ -596,9 +596,10 @@ namespace gl
|
||||||
u16 x, u16 y, u16 width, u16 height, const texture_channel_remap_t& remap, bool copy)
|
u16 x, u16 y, u16 width, u16 height, const texture_channel_remap_t& remap, bool copy)
|
||||||
{
|
{
|
||||||
if (sized_internal_fmt == GL_NONE)
|
if (sized_internal_fmt == GL_NONE)
|
||||||
|
{
|
||||||
sized_internal_fmt = gl::get_sized_internal_format(gcm_format);
|
sized_internal_fmt = gl::get_sized_internal_format(gcm_format);
|
||||||
|
}
|
||||||
|
|
||||||
const auto ifmt = static_cast<gl::texture::internal_format>(sized_internal_fmt);
|
|
||||||
std::unique_ptr<gl::texture> dst = std::make_unique<gl::viewable_image>(dst_type, width, height, 1, 1, sized_internal_fmt);
|
std::unique_ptr<gl::texture> dst = std::make_unique<gl::viewable_image>(dst_type, width, height, 1, 1, sized_internal_fmt);
|
||||||
|
|
||||||
if (copy)
|
if (copy)
|
||||||
|
@ -615,15 +616,9 @@ namespace gl
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<GLenum, 4> swizzle;
|
std::array<GLenum, 4> swizzle;
|
||||||
if (!src || (GLenum)ifmt != sized_internal_fmt)
|
if (!src || (GLenum)src->get_internal_format() != sized_internal_fmt)
|
||||||
{
|
{
|
||||||
if (src)
|
// Apply base component map onto the new texture if a data cast has been done
|
||||||
{
|
|
||||||
//Format mismatch
|
|
||||||
warn_once("GL format mismatch (data cast?). Sized ifmt=0x%X vs Src ifmt=0x%X", sized_internal_fmt, (GLenum)ifmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Apply base component map onto the new texture if a data cast has been done
|
|
||||||
swizzle = get_component_mapping(gcm_format, rsx::texture_create_flags::default_component_order);
|
swizzle = get_component_mapping(gcm_format, rsx::texture_create_flags::default_component_order);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -685,8 +680,8 @@ namespace gl
|
||||||
if (!slice.src)
|
if (!slice.src)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto src_bpp = slice.src->pitch() / slice.src->width();
|
const bool typeless = dst_aspect != slice.src->aspect() ||
|
||||||
const bool typeless = dst_bpp != src_bpp || dst_aspect != slice.src->aspect();
|
!formats_are_bitcast_compatible((GLenum)slice.src->get_internal_format(), (GLenum)dst_image->get_internal_format());
|
||||||
|
|
||||||
auto src_image = slice.src;
|
auto src_image = slice.src;
|
||||||
auto src_x = slice.src_x;
|
auto src_x = slice.src_x;
|
||||||
|
@ -694,6 +689,7 @@ namespace gl
|
||||||
|
|
||||||
if (UNLIKELY(typeless))
|
if (UNLIKELY(typeless))
|
||||||
{
|
{
|
||||||
|
const auto src_bpp = slice.src->pitch() / slice.src->width();
|
||||||
const u16 convert_w = u16(slice.src->width() * src_bpp) / dst_bpp;
|
const u16 convert_w = u16(slice.src->width() * src_bpp) / dst_bpp;
|
||||||
tmp = std::make_unique<texture>(GL_TEXTURE_2D, convert_w, slice.src->height(), 1, 1, (GLenum)dst_image->get_internal_format());
|
tmp = std::make_unique<texture>(GL_TEXTURE_2D, convert_w, slice.src->height(), 1, 1, (GLenum)dst_image->get_internal_format());
|
||||||
|
|
||||||
|
@ -842,10 +838,17 @@ namespace gl
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_image_contents(gl::command_context&, gl::texture_view* dst, gl::texture* src, u16 width, u16 height) override
|
void update_image_contents(gl::command_context& cmd, gl::texture_view* dst, gl::texture* src, u16 width, u16 height) override
|
||||||
{
|
{
|
||||||
glCopyImageSubData(src->id(), GL_TEXTURE_2D, 0, 0, 0, 0,
|
std::vector<copy_region_descriptor> region =
|
||||||
dst->image()->id(), GL_TEXTURE_2D, 0, 0, 0, 0, width, height, 1);
|
{{
|
||||||
|
src,
|
||||||
|
surface_transform::identity,
|
||||||
|
0, 0, 0, 0, 0,
|
||||||
|
width, height, width, height
|
||||||
|
}};
|
||||||
|
|
||||||
|
copy_transfer_regions_impl(cmd, dst->image(), region);
|
||||||
}
|
}
|
||||||
|
|
||||||
cached_texture_section* create_new_texture(gl::command_context&, const utils::address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch,
|
cached_texture_section* create_new_texture(gl::command_context&, const utils::address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch,
|
||||||
|
|
|
@ -368,4 +368,82 @@ namespace vk
|
||||||
|
|
||||||
fmt::throw_exception("Unexpected vkFormat 0x%X", (u32)format);
|
fmt::throw_exception("Unexpected vkFormat 0x%X", (u32)format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<bool, u32> get_format_convert_flags(VkFormat format)
|
||||||
|
{
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
//8-bit
|
||||||
|
case VK_FORMAT_R8_UNORM:
|
||||||
|
case VK_FORMAT_R8G8_UNORM:
|
||||||
|
case VK_FORMAT_R8G8_SNORM:
|
||||||
|
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
|
||||||
|
case VK_FORMAT_R8G8B8A8_UNORM:
|
||||||
|
return{ false, 1 };
|
||||||
|
case VK_FORMAT_B8G8R8A8_UNORM:
|
||||||
|
case VK_FORMAT_B8G8R8A8_SRGB:
|
||||||
|
return{ true, 4 };
|
||||||
|
//16-bit
|
||||||
|
case VK_FORMAT_R16_UINT:
|
||||||
|
case VK_FORMAT_R16_SFLOAT:
|
||||||
|
case VK_FORMAT_R16_UNORM:
|
||||||
|
case VK_FORMAT_R16G16_UNORM:
|
||||||
|
case VK_FORMAT_R16G16_SFLOAT:
|
||||||
|
case VK_FORMAT_R16G16B16A16_SFLOAT:
|
||||||
|
case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
|
||||||
|
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
|
||||||
|
case VK_FORMAT_R5G6B5_UNORM_PACK16:
|
||||||
|
case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
|
||||||
|
return{ true, 2 };
|
||||||
|
//32-bit
|
||||||
|
case VK_FORMAT_R32_UINT:
|
||||||
|
case VK_FORMAT_R32_SFLOAT:
|
||||||
|
case VK_FORMAT_R32G32B32A32_SFLOAT:
|
||||||
|
return{ true, 4 };
|
||||||
|
//DXT
|
||||||
|
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
|
||||||
|
case VK_FORMAT_BC2_UNORM_BLOCK:
|
||||||
|
case VK_FORMAT_BC3_UNORM_BLOCK:
|
||||||
|
case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
|
||||||
|
case VK_FORMAT_BC2_SRGB_BLOCK:
|
||||||
|
case VK_FORMAT_BC3_SRGB_BLOCK:
|
||||||
|
return{ false, 1 };
|
||||||
|
//Depth
|
||||||
|
case VK_FORMAT_D16_UNORM:
|
||||||
|
return{ true, 2 };
|
||||||
|
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
||||||
|
case VK_FORMAT_D24_UNORM_S8_UINT:
|
||||||
|
return{ true, 4 };
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt::throw_exception("Unknown vkFormat 0x%x" HERE, (u32)format);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool formats_are_bitcast_compatible(VkFormat format1, VkFormat format2)
|
||||||
|
{
|
||||||
|
if (LIKELY(format1 == format2))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Formats are compatible if the following conditions are met:
|
||||||
|
// 1. Texel sizes must match
|
||||||
|
// 2. Both formats require no transforms (basic memcpy) or...
|
||||||
|
// 3. Both formats have the same transform (e.g RG16_UNORM to RG16_SFLOAT, both are down and uploaded with a 2-byte byteswap)
|
||||||
|
|
||||||
|
if (get_format_texel_width(format1) != get_format_texel_width(format2))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto transform_a = get_format_convert_flags(format1);
|
||||||
|
const auto transform_b = get_format_convert_flags(format2);
|
||||||
|
|
||||||
|
if (transform_a.first == transform_b.first)
|
||||||
|
{
|
||||||
|
return !transform_a.first || (transform_a.second == transform_b.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ namespace vk
|
||||||
VkFormat get_compatible_srgb_format(VkFormat rgb_format);
|
VkFormat get_compatible_srgb_format(VkFormat rgb_format);
|
||||||
u8 get_format_texel_width(VkFormat format);
|
u8 get_format_texel_width(VkFormat format);
|
||||||
std::pair<u8, u8> get_format_element_size(VkFormat format);
|
std::pair<u8, u8> get_format_element_size(VkFormat format);
|
||||||
|
std::pair<bool, u32> get_format_convert_flags(VkFormat format);
|
||||||
|
bool formats_are_bitcast_compatible(VkFormat format1, VkFormat format2);
|
||||||
|
|
||||||
std::tuple<VkFilter, VkSamplerMipmapMode> get_min_filter_and_mip(rsx::texture_minify_filter min_filter);
|
std::tuple<VkFilter, VkSamplerMipmapMode> get_min_filter_and_mip(rsx::texture_minify_filter min_filter);
|
||||||
VkFilter get_mag_filter(rsx::texture_magnify_filter mag_filter);
|
VkFilter get_mag_filter(rsx::texture_magnify_filter mag_filter);
|
||||||
|
|
|
@ -118,7 +118,8 @@ namespace vk
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (src_bpp != dst_bpp || src_texture->attachment_aspect_flag != attachment_aspect_flag)
|
if (!formats_are_bitcast_compatible(format(), src_texture->format()) ||
|
||||||
|
src_texture->attachment_aspect_flag != attachment_aspect_flag)
|
||||||
{
|
{
|
||||||
typeless_info.src_is_typeless = true;
|
typeless_info.src_is_typeless = true;
|
||||||
typeless_info.src_context = rsx::texture_upload_context::framebuffer_storage;
|
typeless_info.src_context = rsx::texture_upload_context::framebuffer_storage;
|
||||||
|
|
|
@ -56,56 +56,6 @@ namespace vk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, u32> get_format_convert_flags(VkFormat format)
|
|
||||||
{
|
|
||||||
switch (format)
|
|
||||||
{
|
|
||||||
//8-bit
|
|
||||||
case VK_FORMAT_R8_UNORM:
|
|
||||||
case VK_FORMAT_R8G8_UNORM:
|
|
||||||
case VK_FORMAT_R8G8_SNORM:
|
|
||||||
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
|
|
||||||
case VK_FORMAT_R8G8B8A8_UNORM:
|
|
||||||
return{ false, 1 };
|
|
||||||
case VK_FORMAT_B8G8R8A8_UNORM:
|
|
||||||
case VK_FORMAT_B8G8R8A8_SRGB:
|
|
||||||
return{ true, 4 };
|
|
||||||
//16-bit
|
|
||||||
case VK_FORMAT_R16_UINT:
|
|
||||||
case VK_FORMAT_R16_SFLOAT:
|
|
||||||
case VK_FORMAT_R16_UNORM:
|
|
||||||
case VK_FORMAT_R16G16_UNORM:
|
|
||||||
case VK_FORMAT_R16G16_SFLOAT:
|
|
||||||
case VK_FORMAT_R16G16B16A16_SFLOAT:
|
|
||||||
case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
|
|
||||||
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
|
|
||||||
case VK_FORMAT_R5G6B5_UNORM_PACK16:
|
|
||||||
case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
|
|
||||||
return{ true, 2 };
|
|
||||||
//32-bit
|
|
||||||
case VK_FORMAT_R32_UINT:
|
|
||||||
case VK_FORMAT_R32_SFLOAT:
|
|
||||||
case VK_FORMAT_R32G32B32A32_SFLOAT:
|
|
||||||
return{ true, 4 };
|
|
||||||
//DXT
|
|
||||||
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
|
|
||||||
case VK_FORMAT_BC2_UNORM_BLOCK:
|
|
||||||
case VK_FORMAT_BC3_UNORM_BLOCK:
|
|
||||||
case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
|
|
||||||
case VK_FORMAT_BC2_SRGB_BLOCK:
|
|
||||||
case VK_FORMAT_BC3_SRGB_BLOCK:
|
|
||||||
return{ false, 1 };
|
|
||||||
//Depth
|
|
||||||
case VK_FORMAT_D16_UNORM:
|
|
||||||
return{ true, 2 };
|
|
||||||
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
|
||||||
case VK_FORMAT_D24_UNORM_S8_UINT:
|
|
||||||
return{ true, 4 };
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt::throw_exception("Unknown vkFormat 0x%x" HERE, (u32)format);
|
|
||||||
}
|
|
||||||
|
|
||||||
void copy_image_to_buffer(VkCommandBuffer cmd, const vk::image* src, const vk::buffer* dst, const VkBufferImageCopy& region)
|
void copy_image_to_buffer(VkCommandBuffer cmd, const vk::image* src, const vk::buffer* dst, const VkBufferImageCopy& region)
|
||||||
{
|
{
|
||||||
switch (src->format())
|
switch (src->format())
|
||||||
|
|
|
@ -506,8 +506,8 @@ namespace vk
|
||||||
if (!section.src)
|
if (!section.src)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto src_bpp = vk::get_format_texel_width(section.src->format());
|
const bool typeless = section.src->aspect() != dst_aspect ||
|
||||||
const bool typeless = section.src->aspect() != dst_aspect || src_bpp != dst_bpp;
|
!formats_are_bitcast_compatible(dst->format(), section.src->format());
|
||||||
|
|
||||||
section.src->push_layout(cmd, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
section.src->push_layout(cmd, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||||
|
|
||||||
|
@ -517,6 +517,7 @@ namespace vk
|
||||||
src_image = vk::get_typeless_helper(dst->info.format, section.src_x + section.src_w, section.src_y + section.src_h);
|
src_image = vk::get_typeless_helper(dst->info.format, section.src_x + section.src_w, section.src_y + section.src_h);
|
||||||
src_image->change_layout(cmd, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
src_image->change_layout(cmd, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
|
||||||
|
const auto src_bpp = vk::get_format_texel_width(section.src->format());
|
||||||
const u16 convert_w = u16(section.src_w * dst_bpp) / src_bpp;
|
const u16 convert_w = u16(section.src_w * dst_bpp) / src_bpp;
|
||||||
const areai src_rect = coordi{{ section.src_x, section.src_y }, { convert_w, section.src_h }};
|
const areai src_rect = coordi{{ section.src_x, section.src_y }, { convert_w, section.src_h }};
|
||||||
const areai dst_rect = coordi{{ section.src_x, section.src_y }, { section.src_w, section.src_h }};
|
const areai dst_rect = coordi{{ section.src_x, section.src_y }, { section.src_w, section.src_h }};
|
||||||
|
@ -874,25 +875,18 @@ namespace vk
|
||||||
|
|
||||||
void update_image_contents(vk::command_buffer& cmd, vk::image_view* dst_view, vk::image* src, u16 width, u16 height) override
|
void update_image_contents(vk::command_buffer& cmd, vk::image_view* dst_view, vk::image* src, u16 width, u16 height) override
|
||||||
{
|
{
|
||||||
VkImage dst = dst_view->info.image;
|
std::vector<copy_region_descriptor> region =
|
||||||
VkImageAspectFlags aspect = vk::get_aspect_flags(src->info.format);
|
{{
|
||||||
VkImageSubresourceRange subresource_range = { aspect, 0, 1, 0, 1 };
|
src,
|
||||||
vk::change_image_layout(cmd, dst, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, subresource_range);
|
surface_transform::identity,
|
||||||
|
0, 0, 0, 0, 0,
|
||||||
|
width, height, width, height
|
||||||
|
}};
|
||||||
|
|
||||||
VkImageLayout old_src_layout = src->current_layout;
|
auto dst = dst_view->image();
|
||||||
vk::change_image_layout(cmd, src, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, subresource_range);
|
dst->push_layout(cmd, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
copy_transfer_regions_impl(cmd, dst, region);
|
||||||
VkImageCopy copy_rgn;
|
dst->pop_layout(cmd);
|
||||||
copy_rgn.srcOffset = { 0, 0, 0 };
|
|
||||||
copy_rgn.dstOffset = { 0, 0, 0 };
|
|
||||||
copy_rgn.dstSubresource = { aspect & ~(VK_IMAGE_ASPECT_DEPTH_BIT), 0, 0, 1 };
|
|
||||||
copy_rgn.srcSubresource = { aspect & ~(VK_IMAGE_ASPECT_DEPTH_BIT), 0, 0, 1 };
|
|
||||||
copy_rgn.extent = { width, height, 1 };
|
|
||||||
|
|
||||||
vkCmdCopyImage(cmd, src->value, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_rgn);
|
|
||||||
|
|
||||||
vk::change_image_layout(cmd, src, old_src_layout, subresource_range);
|
|
||||||
vk::change_image_layout(cmd, dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, subresource_range);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cached_texture_section* create_new_texture(vk::command_buffer& cmd, const utils::address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch,
|
cached_texture_section* create_new_texture(vk::command_buffer& cmd, const utils::address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue