mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 16:31:28 +12:00
rsx: Texture cache fixes
- Fix src/dst framebuffer detection - Silence some warnings
This commit is contained in:
parent
c63ff05e6e
commit
eab9d06981
3 changed files with 56 additions and 74 deletions
|
@ -897,6 +897,21 @@ namespace rsx
|
||||||
|
|
||||||
u32 framebuffer_src_address = src_address;
|
u32 framebuffer_src_address = src_address;
|
||||||
|
|
||||||
|
float scale_x = dst.scale_x;
|
||||||
|
float scale_y = dst.scale_y;
|
||||||
|
|
||||||
|
//TODO: Investigate effects of compression in X axis
|
||||||
|
if (dst.compressed_y)
|
||||||
|
scale_y *= 0.5f;
|
||||||
|
|
||||||
|
if (src.compressed_y)
|
||||||
|
scale_y *= 2.f;
|
||||||
|
|
||||||
|
//Offset in x and y for src is 0 (it is already accounted for when getting pixels_src)
|
||||||
|
//Reproject final clip onto source...
|
||||||
|
const u16 src_w = (const u16)((f32)dst.clip_width / scale_x);
|
||||||
|
const u16 src_h = (const u16)((f32)dst.clip_height / scale_y);
|
||||||
|
|
||||||
//Correct for tile compression
|
//Correct for tile compression
|
||||||
//TODO: Investigate whether DST compression also affects alignment
|
//TODO: Investigate whether DST compression also affects alignment
|
||||||
if (src.compressed_x || src.compressed_y)
|
if (src.compressed_x || src.compressed_y)
|
||||||
|
@ -908,75 +923,67 @@ namespace rsx
|
||||||
framebuffer_src_address -= (x_bytes + y_bytes);
|
framebuffer_src_address -= (x_bytes + y_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 max_dst_width = dst.width;
|
|
||||||
u16 max_dst_height = dst.height;
|
|
||||||
|
|
||||||
float scale_x = dst.scale_x;
|
|
||||||
float scale_y = dst.scale_y;
|
|
||||||
|
|
||||||
//TODO: Investigate effects of compression in X axis
|
|
||||||
if (dst.compressed_y)
|
|
||||||
{
|
|
||||||
scale_y *= 0.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (src.compressed_y)
|
|
||||||
{
|
|
||||||
scale_y *= 2.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Offset in x and y for src is 0 (it is already accounted for when getting pixels_src)
|
|
||||||
//Reproject final clip onto source...
|
|
||||||
const u16 src_w = (const u16)((f32)dst.clip_width / scale_x);
|
|
||||||
const u16 src_h = (const u16)((f32)dst.clip_height / scale_y);
|
|
||||||
|
|
||||||
areai src_area = { 0, 0, src_w, src_h };
|
|
||||||
areai dst_area = { 0, 0, dst.clip_width, dst.clip_height };
|
|
||||||
|
|
||||||
//Check if src/dst are parts of render targets
|
//Check if src/dst are parts of render targets
|
||||||
auto dst_subres = m_rtts.get_surface_subresource_if_applicable(dst_address, dst.width, dst.clip_height, dst.pitch, true, true, false, dst.compressed_y);
|
auto dst_subres = m_rtts.get_surface_subresource_if_applicable(dst_address, dst.width, dst.clip_height, dst.pitch, true, true, false, dst.compressed_y);
|
||||||
dst_is_render_target = dst_subres.surface != nullptr;
|
dst_is_render_target = dst_subres.surface != nullptr;
|
||||||
|
|
||||||
|
if (dst_is_render_target && dst_subres.surface->get_native_pitch() != dst.pitch)
|
||||||
|
{
|
||||||
|
//Surface pitch is invalid if it is less that the rsx pitch (usually set to 64 in such a case)
|
||||||
|
if (dst_subres.surface->get_rsx_pitch() != dst.pitch ||
|
||||||
|
dst.pitch < dst_subres.surface->get_native_pitch())
|
||||||
|
dst_is_render_target = false;
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: Handle cases where src or dst can be a depth texture while the other is a color texture - requires a render pass to emulate
|
//TODO: Handle cases where src or dst can be a depth texture while the other is a color texture - requires a render pass to emulate
|
||||||
auto src_subres = m_rtts.get_surface_subresource_if_applicable(framebuffer_src_address, src_w, src_h, src.pitch, true, true, false, src.compressed_y);
|
auto src_subres = m_rtts.get_surface_subresource_if_applicable(framebuffer_src_address, src_w, src_h, src.pitch, true, true, false, src.compressed_y);
|
||||||
src_is_render_target = src_subres.surface != nullptr;
|
src_is_render_target = src_subres.surface != nullptr;
|
||||||
|
|
||||||
|
if (src_is_render_target && src_subres.surface->get_native_pitch() != src.pitch)
|
||||||
|
{
|
||||||
|
//Surface pitch is invalid if it is less that the rsx pitch (usually set to 64 in such a case)
|
||||||
|
if (src_subres.surface->get_rsx_pitch() != src.pitch ||
|
||||||
|
src.pitch < src_subres.surface->get_native_pitch())
|
||||||
|
src_is_render_target = false;
|
||||||
|
}
|
||||||
|
|
||||||
//Always use GPU blit if src or dst is in the surface store
|
//Always use GPU blit if src or dst is in the surface store
|
||||||
if (!g_cfg.video.use_gpu_texture_scaling && !(src_is_render_target || dst_is_render_target))
|
if (!g_cfg.video.use_gpu_texture_scaling && !(src_is_render_target || dst_is_render_target))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//1024 height is a hack (for ~720p buffers)
|
reader_lock lock(m_cache_mutex);
|
||||||
//It is possible to have a large buffer that goes up to around 4kx4k but anything above 1280x720 is rare
|
|
||||||
//RSX only handles 512x512 tiles so texture 'stitching' will eventually be needed to be completely accurate
|
|
||||||
//Sections will be submitted as (512x512 + 512x512 + 256x512 + 512x208 + 512x208 + 256x208) to blit a 720p surface to the backbuffer for example
|
|
||||||
int practical_height;
|
|
||||||
if (dst.max_tile_h < dst.height || !src_is_render_target)
|
|
||||||
practical_height = (s32)dst.height;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Hack
|
|
||||||
practical_height = std::min((s32)dst.max_tile_h, 1024);
|
|
||||||
}
|
|
||||||
|
|
||||||
size2i dst_dimensions = { dst.pitch / (dst_is_argb8 ? 4 : 2), practical_height };
|
|
||||||
|
|
||||||
//Check if trivial memcpy can perform the same task
|
//Check if trivial memcpy can perform the same task
|
||||||
//Used to copy programs to the GPU in some cases
|
//Used to copy programs to the GPU in some cases
|
||||||
bool is_memcpy = false;
|
|
||||||
u32 memcpy_bytes_length = 0;
|
|
||||||
|
|
||||||
if (!src_is_render_target && !dst_is_render_target && dst_is_argb8 == src_is_argb8 && !dst.swizzled)
|
if (!src_is_render_target && !dst_is_render_target && dst_is_argb8 == src_is_argb8 && !dst.swizzled)
|
||||||
{
|
{
|
||||||
if ((src.slice_h == 1 && dst.clip_height == 1) ||
|
if ((src.slice_h == 1 && dst.clip_height == 1) ||
|
||||||
(dst.clip_width == src.width && dst.clip_height == src.slice_h && src.pitch == dst.pitch))
|
(dst.clip_width == src.width && dst.clip_height == src.slice_h && src.pitch == dst.pitch))
|
||||||
{
|
{
|
||||||
const u8 bpp = dst_is_argb8 ? 4 : 2;
|
const u8 bpp = dst_is_argb8 ? 4 : 2;
|
||||||
is_memcpy = true;
|
const u32 memcpy_bytes_length = dst.clip_width * bpp * dst.clip_height;
|
||||||
memcpy_bytes_length = dst.clip_width * bpp * dst.clip_height;
|
|
||||||
|
lock.upgrade();
|
||||||
|
flush_address_impl(src_address, std::forward<Args>(extras)...);
|
||||||
|
invalidate_range_impl(dst_address, memcpy_bytes_length, true);
|
||||||
|
memcpy(dst.pixels, src.pixels, memcpy_bytes_length);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reader_lock lock(m_cache_mutex);
|
u16 max_dst_width = dst.width;
|
||||||
|
u16 max_dst_height = dst.height;
|
||||||
|
areai src_area = { 0, 0, src_w, src_h };
|
||||||
|
areai dst_area = { 0, 0, dst.clip_width, dst.clip_height };
|
||||||
|
|
||||||
|
//1024 height is a hack (for ~720p buffers)
|
||||||
|
//It is possible to have a large buffer that goes up to around 4kx4k but anything above 1280x720 is rare
|
||||||
|
//RSX only handles 512x512 tiles so texture 'stitching' will eventually be needed to be completely accurate
|
||||||
|
//Sections will be submitted as (512x512 + 512x512 + 256x512 + 512x208 + 512x208 + 256x208) to blit a 720p surface to the backbuffer for example
|
||||||
|
size2i dst_dimensions = { dst.pitch / (dst_is_argb8 ? 4 : 2), dst.height };
|
||||||
|
if (dst.max_tile_h > dst.height && src_is_render_target)
|
||||||
|
dst_dimensions.height = std::min((s32)dst.max_tile_h, 1024);
|
||||||
|
|
||||||
section_storage_type* cached_dest = nullptr;
|
section_storage_type* cached_dest = nullptr;
|
||||||
bool invalidate_dst_range = false;
|
bool invalidate_dst_range = false;
|
||||||
|
|
||||||
|
@ -1027,14 +1034,6 @@ namespace rsx
|
||||||
//Prep surface
|
//Prep surface
|
||||||
enforce_surface_creation_type(*cached_dest, dst.swizzled ? rsx::texture_create_flags::swapped_native_component_order : rsx::texture_create_flags::native_component_order);
|
enforce_surface_creation_type(*cached_dest, dst.swizzled ? rsx::texture_create_flags::swapped_native_component_order : rsx::texture_create_flags::native_component_order);
|
||||||
}
|
}
|
||||||
else if (is_memcpy)
|
|
||||||
{
|
|
||||||
lock.upgrade();
|
|
||||||
flush_address_impl(src_address, std::forward<Args>(extras)...);
|
|
||||||
invalidate_range_impl(dst_address, memcpy_bytes_length, true);
|
|
||||||
memcpy(dst.pixels, src.pixels, memcpy_bytes_length);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (overlapping_surfaces.size() > 0)
|
else if (overlapping_surfaces.size() > 0)
|
||||||
{
|
{
|
||||||
invalidate_dst_range = true;
|
invalidate_dst_range = true;
|
||||||
|
@ -1053,23 +1052,6 @@ namespace rsx
|
||||||
|
|
||||||
max_dst_width = dst_subres.surface->get_surface_width();
|
max_dst_width = dst_subres.surface->get_surface_width();
|
||||||
max_dst_height = dst_subres.surface->get_surface_height();
|
max_dst_height = dst_subres.surface->get_surface_height();
|
||||||
|
|
||||||
if (is_memcpy)
|
|
||||||
{
|
|
||||||
//Some render target descriptions are actually invalid
|
|
||||||
//Confirm this is a flushable RTT
|
|
||||||
const auto rsx_pitch = dst_subres.surface->get_rsx_pitch();
|
|
||||||
const auto native_pitch = dst_subres.surface->get_native_pitch();
|
|
||||||
|
|
||||||
if (rsx_pitch <= 64 && native_pitch != rsx_pitch)
|
|
||||||
{
|
|
||||||
lock.upgrade();
|
|
||||||
flush_address_impl(src_address, std::forward<Args>(extras)...);
|
|
||||||
invalidate_range_impl(dst_address, memcpy_bytes_length, true);
|
|
||||||
memcpy(dst.pixels, src.pixels, memcpy_bytes_length);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create source texture if does not exist
|
//Create source texture if does not exist
|
||||||
|
|
|
@ -240,7 +240,7 @@ namespace gl
|
||||||
real_pitch = 0;
|
real_pitch = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_dimensions(u32 width, u32 height, u32 depth, u32 pitch)
|
void set_dimensions(u32 width, u32 height, u32 /*depth*/, u32 pitch)
|
||||||
{
|
{
|
||||||
this->width = width;
|
this->width = width;
|
||||||
this->height = height;
|
this->height = height;
|
||||||
|
@ -643,7 +643,7 @@ namespace gl
|
||||||
|
|
||||||
cached_texture_section* create_new_texture(void*&, u32 rsx_address, u32 rsx_size, u16 width, u16 height, u16 depth, u16 mipmaps, const u32 gcm_format,
|
cached_texture_section* create_new_texture(void*&, u32 rsx_address, u32 rsx_size, u16 width, u16 height, u16 depth, u16 mipmaps, const u32 gcm_format,
|
||||||
const rsx::texture_upload_context context, const rsx::texture_dimension_extended type, const rsx::texture_create_flags flags,
|
const rsx::texture_upload_context context, const rsx::texture_dimension_extended type, const rsx::texture_create_flags flags,
|
||||||
std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) override
|
std::pair<std::array<u8, 4>, std::array<u8, 4>>& /*remap_vector*/) override
|
||||||
{
|
{
|
||||||
u32 vram_texture = gl::create_texture(gcm_format, width, height, depth, mipmaps, type);
|
u32 vram_texture = gl::create_texture(gcm_format, width, height, depth, mipmaps, type);
|
||||||
bool depth_flag = false;
|
bool depth_flag = false;
|
||||||
|
|
|
@ -357,7 +357,7 @@ namespace vk
|
||||||
tex.release_dma_resources();
|
tex.release_dma_resources();
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::image_view* create_temporary_subresource_view(vk::command_buffer& cmd, vk::image* source, u32 gcm_format, u16 x, u16 y, u16 w, u16 h) override
|
vk::image_view* create_temporary_subresource_view(vk::command_buffer& cmd, vk::image* source, u32 /*gcm_format*/, u16 x, u16 y, u16 w, u16 h) override
|
||||||
{
|
{
|
||||||
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
|
||||||
|
@ -675,7 +675,7 @@ namespace vk
|
||||||
{
|
{
|
||||||
vk::command_buffer* commands;
|
vk::command_buffer* commands;
|
||||||
blit_helper(vk::command_buffer *c) : commands(c) {}
|
blit_helper(vk::command_buffer *c) : commands(c) {}
|
||||||
void scale_image(vk::image* src, vk::image* dst, areai src_area, areai dst_area, bool interpolate, bool is_depth)
|
void scale_image(vk::image* src, vk::image* dst, areai src_area, areai dst_area, bool /*interpolate*/, bool is_depth)
|
||||||
{
|
{
|
||||||
VkImageAspectFlagBits aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
VkImageAspectFlagBits aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
if (is_depth) aspect = (VkImageAspectFlagBits)(src->info.format == VK_FORMAT_D16_UNORM ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
|
if (is_depth) aspect = (VkImageAspectFlagBits)(src->info.format == VK_FORMAT_D16_UNORM ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue