diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 98eb58bf62..9920e33d06 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -370,6 +370,7 @@ namespace rsx virtual void set_up_remap_vector(section_storage_type& section, const std::pair, std::array>& remap_vector) = 0; virtual void insert_texture_barrier(commandbuffer_type&, image_storage_type* tex) = 0; virtual image_view_type generate_cubemap_from_images(commandbuffer_type&, u32 gcm_format, u16 size, const std::array& sources) = 0; + virtual bool render_target_format_is_compatible(image_storage_type* tex, u32 gcm_format) = 0; constexpr u32 get_block_size() const { return 0x1000000; } inline u32 get_block_address(u32 address) const { return (address & ~0xFFFFFF); } @@ -1385,6 +1386,12 @@ namespace rsx } } + if (!requires_processing) + { + //Check if we need to do anything about the formats + requires_processing = !render_target_format_is_compatible(texptr, format); + } + if (requires_processing) { const auto w = rsx::apply_resolution_scale(internal_width, true); diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index ba796fe7cd..e26ea42dbf 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -947,6 +947,35 @@ namespace gl glTextureBarrierNV(); } + bool render_target_format_is_compatible(gl::texture* tex, u32 gcm_format) override + { + if (auto as_rtt = dynamic_cast(tex)) + { + auto ifmt = as_rtt->get_compatible_internal_format(); + switch (gcm_format) + { + default: + //TODO + LOG_TRACE(RSX, "Format incompatibility detected, reporting failure to force data copy (GL_INTERNAL_FORMAT=0x%X, GCM_FORMAT=0x%X)", (u32)ifmt, gcm_format); + return false; + case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: + return (ifmt == gl::texture::internal_format::rgba16f); + case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: + return (ifmt == gl::texture::internal_format::rgba32f); + case CELL_GCM_TEXTURE_X32_FLOAT: + return (ifmt == gl::texture::internal_format::r32f); + case CELL_GCM_TEXTURE_R5G6B5: + return (ifmt == gl::texture::internal_format::r5g6b5); + case CELL_GCM_TEXTURE_DEPTH24_D8: + return (ifmt == gl::texture::internal_format::depth24_stencil8 || ifmt == gl::texture::internal_format::depth32f_stencil8); + case CELL_GCM_TEXTURE_A8R8G8B8: + return (ifmt == gl::texture::internal_format::rgba8 || ifmt == gl::texture::internal_format::depth24_stencil8 || ifmt == gl::texture::internal_format::depth32f_stencil8); + } + } + + fmt::throw_exception("Format comparison for non-rendertargets is not implemented" HERE); + } + public: texture_cache() {} diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index dd12f7652d..464f4165ad 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -901,6 +901,30 @@ namespace vk vk::insert_texture_barrier(cmd, tex); } + bool render_target_format_is_compatible(vk::image* tex, u32 gcm_format) override + { + auto vk_format = tex->info.format; + switch (gcm_format) + { + default: + //TODO + LOG_TRACE(RSX, "Format incompatibility detected, reporting failure to force data copy (VK_FORMAT=0x%X, GCM_FORMAT=0x%X)", (u32)vk_format, gcm_format); + return false; + case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: + return (vk_format == VK_FORMAT_R16G16B16A16_SFLOAT); + case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: + return (vk_format == VK_FORMAT_R32G32B32A32_SFLOAT); + case CELL_GCM_TEXTURE_X32_FLOAT: + return (vk_format == VK_FORMAT_R32_SFLOAT); + case CELL_GCM_TEXTURE_R5G6B5: + return (vk_format == VK_FORMAT_R5G6B5_UNORM_PACK16); + case CELL_GCM_TEXTURE_DEPTH24_D8: + return (vk_format == VK_FORMAT_D24_UNORM_S8_UINT || vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT); + case CELL_GCM_TEXTURE_A8R8G8B8: + return (vk_format == VK_FORMAT_B8G8R8A8_UNORM || vk_format == VK_FORMAT_D24_UNORM_S8_UINT || vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT); + } + } + public: struct vk_blit_op_result : public blit_op_result