mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 12:05:23 +00:00
vk/gl: Do not sample currently bound render targets
- Create temporary copies for use with the draw call instead
This commit is contained in:
parent
db1a90d828
commit
0cb6dee474
5 changed files with 123 additions and 15 deletions
|
@ -663,15 +663,32 @@ namespace gl
|
|||
/**
|
||||
* Check for sampleable rtts from previous render passes
|
||||
*/
|
||||
gl::texture *texptr = nullptr;
|
||||
gl::render_target *texptr = nullptr;
|
||||
if (texptr = m_rtts.get_texture_from_render_target_if_applicable(texaddr))
|
||||
{
|
||||
for (auto tex : m_rtts.m_bound_render_targets)
|
||||
{
|
||||
if (std::get<0>(tex) == texaddr)
|
||||
{
|
||||
LOG_WARNING(RSX, "Attempting to sample a currently bound render target @ 0x%x", texaddr);
|
||||
create_temporary_subresource(texptr->id(), (GLenum)texptr->get_compatible_internal_format(), 0, 0, texptr->width(), texptr->height());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
texptr->bind();
|
||||
return;
|
||||
}
|
||||
|
||||
if (texptr = m_rtts.get_texture_from_depth_stencil_if_applicable(texaddr))
|
||||
{
|
||||
if (texaddr == std::get<0>(m_rtts.m_bound_depth_stencil))
|
||||
{
|
||||
LOG_WARNING(RSX, "Attempting to sample a currently bound depth surface @ 0x%x", texaddr);
|
||||
create_temporary_subresource(texptr->id(), (GLenum)texptr->get_compatible_internal_format(), 0, 0, texptr->width(), texptr->height());
|
||||
return;
|
||||
}
|
||||
|
||||
texptr->bind();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -123,10 +123,10 @@ namespace vk
|
|||
case VK_FORMAT_R32G32B32A32_SFLOAT:
|
||||
color_format_idx = 3;
|
||||
break;
|
||||
case VK_FORMAT_R8_UINT:
|
||||
case VK_FORMAT_R8_UNORM:
|
||||
color_format_idx = 4;
|
||||
break;
|
||||
case VK_FORMAT_R8G8_UINT:
|
||||
case VK_FORMAT_R8G8_UNORM:
|
||||
color_format_idx = 5;
|
||||
break;
|
||||
case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
|
||||
|
@ -359,7 +359,7 @@ namespace
|
|||
std::array<VkRenderPass, 120> result = {};
|
||||
|
||||
const std::array<VkFormat, 3> depth_format_list = { VK_FORMAT_UNDEFINED, VK_FORMAT_D16_UNORM, gpu_format_support.d24_unorm_s8 ? VK_FORMAT_D24_UNORM_S8_UINT : VK_FORMAT_D32_SFLOAT_S8_UINT };
|
||||
const std::array<VkFormat, 8> color_format_list = { VK_FORMAT_R5G6B5_UNORM_PACK16, VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R32G32B32A32_SFLOAT, VK_FORMAT_R8_UINT, VK_FORMAT_R8G8_UINT, VK_FORMAT_A1R5G5B5_UNORM_PACK16, VK_FORMAT_R32_SFLOAT };
|
||||
const std::array<VkFormat, 8> color_format_list = { VK_FORMAT_R5G6B5_UNORM_PACK16, VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R32G32B32A32_SFLOAT, VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM, VK_FORMAT_A1R5G5B5_UNORM_PACK16, VK_FORMAT_R32_SFLOAT };
|
||||
|
||||
|
||||
for (const VkFormat &color_format : color_format_list)
|
||||
|
@ -1265,6 +1265,7 @@ void VKGSRender::process_swap_request()
|
|||
//m_texture_cache.merge_dirty_textures(m_rtts.invalidated_resources);
|
||||
|
||||
m_rtts.invalidated_resources.clear();
|
||||
m_rtts.invalidate_surface_cache_data(&*m_current_command_buffer);
|
||||
m_texture_cache.flush();
|
||||
|
||||
m_buffer_view_to_clean.clear();
|
||||
|
|
|
@ -255,6 +255,12 @@ namespace vk
|
|||
vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
}
|
||||
|
||||
void change_image_layout(VkCommandBuffer cmd, vk::image *image, VkImageLayout new_layout, VkImageSubresourceRange range)
|
||||
{
|
||||
change_image_layout(cmd, image->value, image->current_layout, new_layout, range);
|
||||
image->current_layout = new_layout;
|
||||
}
|
||||
|
||||
void enter_uninterruptible()
|
||||
{
|
||||
g_cb_no_interrupt_flag = true;
|
||||
|
|
|
@ -56,6 +56,7 @@ namespace vk
|
|||
class swap_chain_image;
|
||||
class physical_device;
|
||||
class command_buffer;
|
||||
struct image;
|
||||
|
||||
vk::context *get_current_thread_ctx();
|
||||
void set_current_thread_ctx(const vk::context &ctx);
|
||||
|
@ -73,6 +74,7 @@ namespace vk
|
|||
void destroy_global_resources();
|
||||
|
||||
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);
|
||||
|
||||
|
@ -358,7 +360,8 @@ namespace vk
|
|||
struct image
|
||||
{
|
||||
VkImage value;
|
||||
VkComponentMapping native_layout = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
|
||||
VkComponentMapping native_component_map = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
|
||||
VkImageLayout current_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
VkImageCreateInfo info = {};
|
||||
std::shared_ptr<vk::memory_block> memory;
|
||||
|
||||
|
@ -416,6 +419,21 @@ namespace vk
|
|||
image(const image&) = delete;
|
||||
image(image&&) = delete;
|
||||
|
||||
u32 width() const
|
||||
{
|
||||
return info.extent.width;
|
||||
}
|
||||
|
||||
u32 height() const
|
||||
{
|
||||
return info.extent.height;
|
||||
}
|
||||
|
||||
u32 depth() const
|
||||
{
|
||||
return info.extent.depth;
|
||||
}
|
||||
|
||||
private:
|
||||
VkDevice m_device;
|
||||
};
|
||||
|
|
|
@ -128,8 +128,7 @@ namespace vk
|
|||
return (protection == utils::protection::rw && uploaded_image_view.get() == nullptr && managed_texture.get() == nullptr);
|
||||
}
|
||||
|
||||
void copy_texture(vk::command_buffer& cmd, u32 heap_index, VkQueue submit_queue,
|
||||
bool manage_cb_lifetime = false, VkImageLayout layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||
void copy_texture(vk::command_buffer& cmd, u32 heap_index, VkQueue submit_queue, bool manage_cb_lifetime = false)
|
||||
{
|
||||
if (m_device == nullptr)
|
||||
{
|
||||
|
@ -172,9 +171,10 @@ namespace vk
|
|||
|
||||
VkImageSubresourceRange subresource_range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
|
||||
|
||||
change_image_layout(cmd, vram_texture->value, layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, subresource_range);
|
||||
VkImageLayout layout = vram_texture->current_layout;
|
||||
change_image_layout(cmd, vram_texture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, subresource_range);
|
||||
vkCmdCopyImageToBuffer(cmd, vram_texture->value, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dma_buffer->value, 1, ©Region);
|
||||
change_image_layout(cmd, vram_texture->value, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, layout, subresource_range);
|
||||
change_image_layout(cmd, vram_texture, layout, subresource_range);
|
||||
|
||||
if (manage_cb_lifetime)
|
||||
{
|
||||
|
@ -227,7 +227,7 @@ namespace vk
|
|||
if (!synchronized)
|
||||
{
|
||||
LOG_WARNING(RSX, "Cache miss at address 0x%X. This is gonna hurt...", cpu_address_base);
|
||||
copy_texture(cmd, heap_index, submit_queue, true, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
copy_texture(cmd, heap_index, submit_queue, true);
|
||||
}
|
||||
|
||||
protect(utils::protection::rw);
|
||||
|
@ -297,7 +297,7 @@ namespace vk
|
|||
return tex;
|
||||
else
|
||||
{
|
||||
LOG_ERROR(RSX, "Cached object for address 0x%X was found, but it does not match stored parameters.");
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -396,6 +396,57 @@ namespace vk
|
|||
return { mapping[1], mapping[2], mapping[3], mapping[0] };
|
||||
}
|
||||
|
||||
vk::image_view* create_temporary_subresource(vk::command_buffer& cmd, vk::image* source, u32 x, u32 y, u32 w, u32 h, const vk::memory_type_mapping &memory_type_mapping)
|
||||
{
|
||||
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
||||
switch (source->info.format)
|
||||
{
|
||||
case VK_FORMAT_D16_UNORM:
|
||||
aspect = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
break;
|
||||
case VK_FORMAT_D24_UNORM_S8_UINT:
|
||||
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
||||
aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
break;
|
||||
}
|
||||
|
||||
VkImageSubresourceRange subresource_range = { aspect, 0, 1, 0, 1 };
|
||||
|
||||
std::unique_ptr<vk::image> image;
|
||||
std::unique_ptr<vk::image_view> view;
|
||||
|
||||
image.reset(new vk::image(*vk::get_current_renderer(), memory_type_mapping.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
source->info.imageType,
|
||||
source->info.format,
|
||||
source->width(), source->height(), source->depth(), 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, source->info.flags));
|
||||
|
||||
VkImageSubresourceRange view_range = { aspect & ~(VK_IMAGE_ASPECT_STENCIL_BIT), 0, 1, 0, 1 };
|
||||
view.reset(new vk::image_view(*vk::get_current_renderer(), image->value, VK_IMAGE_VIEW_TYPE_2D, source->info.format, source->native_component_map, view_range));
|
||||
|
||||
VkImageLayout old_src_layout = source->current_layout;
|
||||
|
||||
vk::change_image_layout(cmd, image.get(), VK_IMAGE_LAYOUT_GENERAL, subresource_range);
|
||||
vk::change_image_layout(cmd, source, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, subresource_range);
|
||||
|
||||
VkImageCopy copy_rgn;
|
||||
copy_rgn.srcOffset = { (s32)x, (s32)y, 0 };
|
||||
copy_rgn.dstOffset = { (s32)x, (s32)y, 0 };
|
||||
copy_rgn.dstSubresource = { aspect, 0, 0, 1 };
|
||||
copy_rgn.srcSubresource = { aspect, 0, 0, 1 };
|
||||
copy_rgn.extent = { w, h, 1 };
|
||||
|
||||
vkCmdCopyImage(cmd, source->value, source->current_layout, image->value, image->current_layout, 1, ©_rgn);
|
||||
vk::change_image_layout(cmd, image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, subresource_range);
|
||||
vk::change_image_layout(cmd, source, old_src_layout, subresource_range);
|
||||
|
||||
m_dirty_textures.push_back(std::move(image));
|
||||
m_temporary_image_view.push_back(std::move(view));
|
||||
|
||||
return m_temporary_image_view.back().get();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
texture_cache() {}
|
||||
|
@ -422,16 +473,31 @@ namespace vk
|
|||
vk::image *rtt_texture = nullptr;
|
||||
if (rtt_texture = m_rtts.get_texture_from_render_target_if_applicable(texaddr))
|
||||
{
|
||||
for (auto tex : m_rtts.m_bound_render_targets)
|
||||
{
|
||||
if (std::get<0>(tex) == texaddr)
|
||||
{
|
||||
LOG_WARNING(RSX, "Attempting to sample a currently bound render target @ 0x%x", texaddr);
|
||||
return create_temporary_subresource(cmd, rtt_texture, 0, 0, rtt_texture->width(), rtt_texture->height(), memory_type_mapping);
|
||||
}
|
||||
}
|
||||
|
||||
m_temporary_image_view.push_back(std::make_unique<vk::image_view>(*vk::get_current_renderer(), rtt_texture->value, VK_IMAGE_VIEW_TYPE_2D, rtt_texture->info.format,
|
||||
rtt_texture->native_layout,
|
||||
rtt_texture->native_component_map,
|
||||
vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT)));
|
||||
return m_temporary_image_view.back().get();
|
||||
}
|
||||
|
||||
if (rtt_texture = m_rtts.get_texture_from_depth_stencil_if_applicable(texaddr))
|
||||
{
|
||||
if (std::get<0>(m_rtts.m_bound_depth_stencil) == texaddr)
|
||||
{
|
||||
LOG_WARNING(RSX, "Attempting to sample a currently bound depth surface @ 0x%x", texaddr);
|
||||
return create_temporary_subresource(cmd, rtt_texture, 0, 0, rtt_texture->width(), rtt_texture->height(), memory_type_mapping);
|
||||
}
|
||||
|
||||
m_temporary_image_view.push_back(std::make_unique<vk::image_view>(*vk::get_current_renderer(), rtt_texture->value, VK_IMAGE_VIEW_TYPE_2D, rtt_texture->info.format,
|
||||
rtt_texture->native_layout,
|
||||
rtt_texture->native_component_map,
|
||||
vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_DEPTH_BIT)));
|
||||
return m_temporary_image_view.back().get();
|
||||
}
|
||||
|
@ -501,7 +567,7 @@ namespace vk
|
|||
vk_format,
|
||||
tex.width(), height, depth, tex.get_exact_mipmap_count(), layer, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, is_cubemap ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0);
|
||||
change_image_layout(cmd, image->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, subresource_range);
|
||||
change_image_layout(cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, subresource_range);
|
||||
|
||||
vk::image_view *view = new vk::image_view(*vk::get_current_renderer(), image->value, image_view_type, vk_format,
|
||||
mapping,
|
||||
|
@ -513,7 +579,7 @@ namespace vk
|
|||
copy_mipmaped_image_using_buffer(cmd, image->value, get_subresources_layout(tex), format, !(tex.format() & CELL_GCM_TEXTURE_LN), tex.get_exact_mipmap_count(),
|
||||
upload_heap, upload_buffer);
|
||||
|
||||
change_image_layout(cmd, image->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, subresource_range);
|
||||
change_image_layout(cmd, image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, subresource_range);
|
||||
|
||||
vk::leave_uninterruptible();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue