mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 18:53:28 +01:00
rsx: Fixes
- Discard intentionally invalidated framebuffer resources. These are created after a flush has happened, forcing reupload since contents cannot be guaranteed (strict mode only) - Fix for blits using vulkan; dont use the copy method if formats do not match, use generic blit instead
This commit is contained in:
parent
145ecb00fc
commit
ddebc334bf
@ -659,26 +659,48 @@ namespace rsx
|
||||
if (found != m_cache.end())
|
||||
{
|
||||
auto &range_data = found->second;
|
||||
std::pair<section_storage_type*, ranged_storage*> best_fit = {};
|
||||
|
||||
for (auto &tex : range_data.data)
|
||||
{
|
||||
if (tex.matches(rsx_address, rsx_size) && !tex.is_dirty())
|
||||
if (tex.matches(rsx_address, rsx_size))
|
||||
{
|
||||
if (!confirm_dimensions || tex.matches(rsx_address, width, height, depth, mipmaps))
|
||||
if (!tex.is_dirty())
|
||||
{
|
||||
if (!tex.is_locked() && tex.get_context() == texture_upload_context::framebuffer_storage)
|
||||
range_data.notify(rsx_address, rsx_size);
|
||||
if (!confirm_dimensions || tex.matches(rsx_address, width, height, depth, mipmaps))
|
||||
{
|
||||
if (!tex.is_locked() && tex.get_context() == texture_upload_context::framebuffer_storage)
|
||||
range_data.notify(rsx_address, rsx_size);
|
||||
|
||||
return tex;
|
||||
return tex;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR(RSX, "Cached object for address 0x%X was found, but it does not match stored parameters.", rsx_address);
|
||||
LOG_ERROR(RSX, "%d x %d vs %d x %d", width, height, tex.get_width(), tex.get_height());
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (!best_fit.first)
|
||||
{
|
||||
LOG_ERROR(RSX, "Cached object for address 0x%X was found, but it does not match stored parameters.", rsx_address);
|
||||
LOG_ERROR(RSX, "%d x %d vs %d x %d", width, height, tex.get_width(), tex.get_height());
|
||||
//By grabbing a ref to a matching entry, duplicates are avoided
|
||||
best_fit = { &tex, &range_data };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (best_fit.first)
|
||||
{
|
||||
if (best_fit.first->exists())
|
||||
{
|
||||
m_unreleased_texture_objects--;
|
||||
free_texture_section(*best_fit.first);
|
||||
m_texture_memory_in_use -= best_fit.first->get_section_size();
|
||||
}
|
||||
|
||||
best_fit.second->notify(rsx_address, rsx_size);
|
||||
return *best_fit.first;
|
||||
}
|
||||
|
||||
for (auto &tex : range_data.data)
|
||||
{
|
||||
if (tex.is_dirty())
|
||||
@ -1344,10 +1366,22 @@ namespace rsx
|
||||
auto cached_texture = find_texture_from_dimensions(texaddr, tex_width, tex_height, depth);
|
||||
if (cached_texture)
|
||||
{
|
||||
if (cached_texture->get_image_type() == rsx::texture_dimension_extended::texture_dimension_1d)
|
||||
scale_y = 0.f;
|
||||
//TODO: Handle invalidated framebuffer textures better. This is awful
|
||||
if (cached_texture->get_context() == rsx::texture_upload_context::framebuffer_storage)
|
||||
{
|
||||
if (!cached_texture->is_locked())
|
||||
{
|
||||
cached_texture->set_dirty(true);
|
||||
m_unreleased_texture_objects++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cached_texture->get_image_type() == rsx::texture_dimension_extended::texture_dimension_1d)
|
||||
scale_y = 0.f;
|
||||
|
||||
return{ cached_texture->get_raw_view(), cached_texture->get_context(), cached_texture->is_depth_texture(), scale_x, scale_y, cached_texture->get_image_type() };
|
||||
return{ cached_texture->get_raw_view(), cached_texture->get_context(), cached_texture->is_depth_texture(), scale_x, scale_y, cached_texture->get_image_type() };
|
||||
}
|
||||
}
|
||||
|
||||
if ((!blit_engine_incompatibility_warning_raised && g_cfg.video.use_gpu_texture_scaling) || is_hw_blit_engine_compatible(format))
|
||||
|
@ -2916,7 +2916,7 @@ void VKGSRender::flip(int buffer)
|
||||
if (image_to_flip)
|
||||
{
|
||||
vk::copy_scaled_image(*m_current_command_buffer, image_to_flip->value, target_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||
0, 0, image_to_flip->width(), image_to_flip->height(), aspect_ratio.x, aspect_ratio.y, aspect_ratio.width, aspect_ratio.height, 1, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
0, 0, image_to_flip->width(), image_to_flip->height(), aspect_ratio.x, aspect_ratio.y, aspect_ratio.width, aspect_ratio.height, 1, VK_IMAGE_ASPECT_COLOR_BIT, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -80,7 +80,7 @@ namespace vk
|
||||
void change_image_layout(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, VkImageSubresourceRange range);
|
||||
void change_image_layout(VkCommandBuffer cmd, vk::image *image, VkImageLayout new_layout, VkImageSubresourceRange range);
|
||||
void copy_image(VkCommandBuffer cmd, VkImage &src, VkImage &dst, VkImageLayout srcLayout, VkImageLayout dstLayout, u32 width, u32 height, u32 mipmaps, VkImageAspectFlagBits aspect);
|
||||
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, VkImageAspectFlagBits aspect);
|
||||
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, VkImageAspectFlagBits aspect, bool compatible_formats);
|
||||
|
||||
VkFormat get_compatible_sampler_format(u32 format);
|
||||
u8 get_format_texel_width(const VkFormat format);
|
||||
|
@ -86,7 +86,7 @@ namespace vk
|
||||
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, VkImageAspectFlagBits aspect)
|
||||
u32 mipmaps, VkImageAspectFlagBits aspect, bool compatible_formats)
|
||||
{
|
||||
VkImageSubresourceLayers a_src = {}, a_dst = {};
|
||||
a_src.aspectMask = aspect;
|
||||
@ -103,7 +103,7 @@ namespace vk
|
||||
if (dstLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
|
||||
change_image_layout(cmd, dst, dstLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk::get_image_subresource_range(0, 0, 1, 1, aspect));
|
||||
|
||||
if (src_width != dst_width || src_height != dst_height || mipmaps > 1)
|
||||
if (src_width != dst_width || src_height != dst_height || mipmaps > 1 || !compatible_formats)
|
||||
{
|
||||
if ((aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0)
|
||||
{
|
||||
|
@ -899,7 +899,7 @@ namespace vk
|
||||
}
|
||||
|
||||
copy_scaled_image(*commands, src->value, dst->value, src->current_layout, dst->current_layout, src_area.x1, src_area.y1, src_area.x2 - src_area.x1, src_area.y2 - src_area.y1,
|
||||
dst_area.x1, dst_area.y1, dst_area.x2 - dst_area.x1, dst_area.y2 - dst_area.y1, 1, aspect);
|
||||
dst_area.x1, dst_area.y1, dst_area.x2 - dst_area.x1, dst_area.y2 - dst_area.y1, 1, aspect, src->info.format == dst->info.format);
|
||||
|
||||
change_image_layout(*commands, dst, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, {(VkImageAspectFlags)aspect, 0, dst->info.mipLevels, 0, dst->info.arrayLayers});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user