diff --git a/src/video_core/rasterizer_cache/rasterizer_cache.h b/src/video_core/rasterizer_cache/rasterizer_cache.h index 2fbc9a671..648d5e4f0 100644 --- a/src/video_core/rasterizer_cache/rasterizer_cache.h +++ b/src/video_core/rasterizer_cache/rasterizer_cache.h @@ -1147,11 +1147,14 @@ bool RasterizerCache::ValidateByReinterpretation(Surface& surface, SurfacePar } const PAddr addr = boost::icl::lower(interval); const SurfaceParams copy_params = surface.FromInterval(copy_interval); - const TextureBlit reinterpret = { + const auto src_rect = src_surface.GetScaledSubRect(copy_params); + const auto dst_rect = surface.GetScaledSubRect(copy_params); + const TextureCopy reinterpret = { .src_level = src_surface.LevelOf(addr), .dst_level = surface.LevelOf(addr), - .src_rect = src_surface.GetScaledSubRect(copy_params), - .dst_rect = surface.GetScaledSubRect(copy_params), + .src_offset = {src_rect.left, src_rect.bottom}, + .dst_offset = {dst_rect.left, dst_rect.bottom}, + .extent = {src_rect.GetWidth(), src_rect.GetHeight()}, }; return runtime.Reinterpret(src_surface, surface, reinterpret); } diff --git a/src/video_core/renderer_opengl/gl_blit_helper.cpp b/src/video_core/renderer_opengl/gl_blit_helper.cpp index 7472b4cc8..830d28e32 100644 --- a/src/video_core/renderer_opengl/gl_blit_helper.cpp +++ b/src/video_core/renderer_opengl/gl_blit_helper.cpp @@ -84,7 +84,7 @@ BlitHelper::BlitHelper(const Driver& driver_) BlitHelper::~BlitHelper() = default; bool BlitHelper::ConvertDS24S8ToRGBA8(Surface& source, Surface& dest, - const VideoCore::TextureBlit& blit) { + const VideoCore::TextureCopy& copy) { OpenGLState prev_state = OpenGLState::GetCurState(); SCOPE_EXIT({ prev_state.Apply(); }); @@ -99,32 +99,35 @@ bool BlitHelper::ConvertDS24S8ToRGBA8(Surface& source, Surface& dest, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } else if (blit.src_rect.top > temp_rect.top || blit.src_rect.right > temp_rect.right) { + } else if (copy.extent.width > temp_extent.width || copy.extent.height > temp_extent.height) { + temp_extent = copy.extent; temp_tex.Release(); temp_tex.Create(); state.texture_units[1].texture_2d = temp_tex.handle; state.Apply(); glActiveTexture(GL_TEXTURE1); - glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, blit.src_rect.right, - blit.src_rect.top); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, temp_extent.width, + temp_extent.height); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - temp_rect = blit.src_rect; } state.texture_units[1].texture_2d = temp_tex.handle; state.Apply(); glActiveTexture(GL_TEXTURE1); if (!use_texture_view) { - glCopyImageSubData(source.Handle(), GL_TEXTURE_2D, 0, blit.src_rect.left, - blit.src_rect.bottom, 0, temp_tex.handle, GL_TEXTURE_2D, 0, - blit.src_rect.left, blit.src_rect.bottom, 0, blit.src_rect.GetWidth(), - blit.src_rect.GetHeight(), 1); + glCopyImageSubData(source.Handle(), GL_TEXTURE_2D, 0, copy.src_offset.x, copy.src_offset.y, + 0, temp_tex.handle, GL_TEXTURE_2D, 0, copy.src_offset.x, + copy.src_offset.y, 0, copy.extent.width, copy.extent.height, 1); } glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX); - SetParams(d24s8_to_rgba8, source.RealExtent(), blit.src_rect); - Draw(d24s8_to_rgba8, dest.Handle(), draw_fbo.handle, 0, blit.dst_rect); + const Common::Rectangle src_rect{copy.src_offset.x, copy.src_offset.y + copy.extent.height, + copy.src_offset.x + copy.extent.width, copy.src_offset.x}; + const Common::Rectangle dst_rect{copy.dst_offset.x, copy.dst_offset.y + copy.extent.height, + copy.dst_offset.x + copy.extent.width, copy.dst_offset.x}; + SetParams(d24s8_to_rgba8, source.RealExtent(), src_rect); + Draw(d24s8_to_rgba8, dest.Handle(), draw_fbo.handle, 0, dst_rect); if (use_texture_view) { temp_tex.Release(); @@ -138,14 +141,18 @@ bool BlitHelper::ConvertDS24S8ToRGBA8(Surface& source, Surface& dest, } bool BlitHelper::ConvertRGBA4ToRGB5A1(Surface& source, Surface& dest, - const VideoCore::TextureBlit& blit) { + const VideoCore::TextureCopy& copy) { OpenGLState prev_state = OpenGLState::GetCurState(); SCOPE_EXIT({ prev_state.Apply(); }); state.texture_units[0].texture_2d = source.Handle(); - SetParams(rgba4_to_rgb5a1, source.RealExtent(), blit.src_rect); - Draw(rgba4_to_rgb5a1, dest.Handle(), draw_fbo.handle, 0, blit.dst_rect); + const Common::Rectangle src_rect{copy.src_offset.x, copy.src_offset.y + copy.extent.height, + copy.src_offset.x + copy.extent.width, copy.src_offset.x}; + const Common::Rectangle dst_rect{copy.dst_offset.x, copy.dst_offset.y + copy.extent.height, + copy.dst_offset.x + copy.extent.width, copy.dst_offset.x}; + SetParams(rgba4_to_rgb5a1, source.RealExtent(), src_rect); + Draw(rgba4_to_rgb5a1, dest.Handle(), draw_fbo.handle, 0, dst_rect); return true; } diff --git a/src/video_core/renderer_opengl/gl_blit_helper.h b/src/video_core/renderer_opengl/gl_blit_helper.h index 01ce770cb..e6ba9cce5 100644 --- a/src/video_core/renderer_opengl/gl_blit_helper.h +++ b/src/video_core/renderer_opengl/gl_blit_helper.h @@ -5,12 +5,14 @@ #pragma once #include "common/math_util.h" +#include "video_core/rasterizer_cache/utils.h" #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_state.h" namespace VideoCore { struct Extent; struct TextureBlit; +struct TextureCopy; } // namespace VideoCore namespace OpenGL { @@ -25,9 +27,9 @@ public: bool Filter(Surface& surface, const VideoCore::TextureBlit& blit); - bool ConvertDS24S8ToRGBA8(Surface& source, Surface& dest, const VideoCore::TextureBlit& blit); + bool ConvertDS24S8ToRGBA8(Surface& source, Surface& dest, const VideoCore::TextureCopy& copy); - bool ConvertRGBA4ToRGB5A1(Surface& source, Surface& dest, const VideoCore::TextureBlit& blit); + bool ConvertRGBA4ToRGB5A1(Surface& source, Surface& dest, const VideoCore::TextureCopy& copy); private: void FilterAnime4K(Surface& surface, const VideoCore::TextureBlit& blit); @@ -68,7 +70,7 @@ private: OGLProgram rgba4_to_rgb5a1; OGLTexture temp_tex; - Common::Rectangle temp_rect{}; + VideoCore::Extent temp_extent{}; bool use_texture_view{true}; }; diff --git a/src/video_core/renderer_opengl/gl_texture_runtime.cpp b/src/video_core/renderer_opengl/gl_texture_runtime.cpp index a45ecc570..f24fe10ac 100644 --- a/src/video_core/renderer_opengl/gl_texture_runtime.cpp +++ b/src/video_core/renderer_opengl/gl_texture_runtime.cpp @@ -170,14 +170,14 @@ const FormatTuple& TextureRuntime::GetFormatTuple(VideoCore::CustomPixelFormat p } bool TextureRuntime::Reinterpret(Surface& source, Surface& dest, - const VideoCore::TextureBlit& blit) { + const VideoCore::TextureCopy& copy) { const PixelFormat src_format = source.pixel_format; const PixelFormat dst_format = dest.pixel_format; ASSERT_MSG(src_format != dst_format, "Reinterpretation with the same format is invalid"); if (src_format == PixelFormat::D24S8 && dst_format == PixelFormat::RGBA8) { - blit_helper.ConvertDS24S8ToRGBA8(source, dest, blit); + blit_helper.ConvertDS24S8ToRGBA8(source, dest, copy); } else if (src_format == PixelFormat::RGBA4 && dst_format == PixelFormat::RGB5A1) { - blit_helper.ConvertRGBA4ToRGB5A1(source, dest, blit); + blit_helper.ConvertRGBA4ToRGB5A1(source, dest, copy); } else { LOG_WARNING(Render_OpenGL, "Unimplemented reinterpretation {} -> {}", VideoCore::PixelFormatAsString(src_format), diff --git a/src/video_core/renderer_opengl/gl_texture_runtime.h b/src/video_core/renderer_opengl/gl_texture_runtime.h index 39da1cac7..9fdc77bc5 100644 --- a/src/video_core/renderer_opengl/gl_texture_runtime.h +++ b/src/video_core/renderer_opengl/gl_texture_runtime.h @@ -59,7 +59,7 @@ public: const FormatTuple& GetFormatTuple(VideoCore::CustomPixelFormat pixel_format); /// Attempts to reinterpret a rectangle of source to another rectangle of dest - bool Reinterpret(Surface& source, Surface& dest, const VideoCore::TextureBlit& blit); + bool Reinterpret(Surface& source, Surface& dest, const VideoCore::TextureCopy& copy); /// Fills the rectangle of the texture with the clear value provided void ClearTexture(Surface& surface, const VideoCore::TextureClear& clear); diff --git a/src/video_core/renderer_vulkan/vk_blit_helper.cpp b/src/video_core/renderer_vulkan/vk_blit_helper.cpp index 1fea0dee5..b9b0875da 100644 --- a/src/video_core/renderer_vulkan/vk_blit_helper.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_helper.cpp @@ -297,7 +297,7 @@ bool BlitHelper::BlitDepthStencil(Surface& source, Surface& dest, } bool BlitHelper::ConvertDS24S8ToRGBA8(Surface& source, Surface& dest, - const VideoCore::TextureBlit& blit) { + const VideoCore::TextureCopy& copy) { std::array textures{}; textures[0].image_info = vk::DescriptorImageInfo{ .imageView = source.DepthView(), @@ -315,7 +315,7 @@ bool BlitHelper::ConvertDS24S8ToRGBA8(Surface& source, Surface& dest, const auto descriptor_set = compute_provider.Acquire(textures); renderpass_cache.EndRendering(); - scheduler.Record([this, descriptor_set, blit, src_image = source.Image(), + scheduler.Record([this, descriptor_set, copy, src_image = source.Image(), dst_image = dest.Image()](vk::CommandBuffer cmdbuf) { const std::array pre_barriers = { vk::ImageMemoryBarrier{ @@ -397,15 +397,15 @@ bool BlitHelper::ConvertDS24S8ToRGBA8(Surface& source, Surface& dest, cmdbuf.bindPipeline(vk::PipelineBindPoint::eCompute, d24s8_to_rgba8_pipeline); const ComputeInfo info = { - .src_offset = Common::Vec2i{static_cast(blit.src_rect.left), - static_cast(blit.src_rect.bottom)}, - .dst_offset = Common::Vec2i{static_cast(blit.dst_rect.left), - static_cast(blit.dst_rect.bottom)}, + .src_offset = Common::Vec2i{static_cast(copy.src_offset.x), + static_cast(copy.src_offset.y)}, + .dst_offset = Common::Vec2i{static_cast(copy.dst_offset.x), + static_cast(copy.dst_offset.y)}, }; cmdbuf.pushConstants(compute_pipeline_layout, vk::ShaderStageFlagBits::eCompute, 0, sizeof(info), &info); - cmdbuf.dispatch(blit.src_rect.GetWidth() / 8, blit.src_rect.GetHeight() / 8, 1); + cmdbuf.dispatch(copy.extent.width / 8, copy.extent.height / 8, 1); cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eComputeShader, vk::PipelineStageFlagBits::eEarlyFragmentTests | diff --git a/src/video_core/renderer_vulkan/vk_blit_helper.h b/src/video_core/renderer_vulkan/vk_blit_helper.h index 785286dbb..b7735fcc9 100644 --- a/src/video_core/renderer_vulkan/vk_blit_helper.h +++ b/src/video_core/renderer_vulkan/vk_blit_helper.h @@ -4,11 +4,11 @@ #pragma once -#include "video_core/rasterizer_cache/pixel_format.h" #include "video_core/renderer_vulkan/vk_descriptor_pool.h" namespace VideoCore { struct TextureBlit; +struct TextureCopy; struct BufferTextureCopy; } // namespace VideoCore @@ -29,7 +29,7 @@ public: bool BlitDepthStencil(Surface& source, Surface& dest, const VideoCore::TextureBlit& blit); - bool ConvertDS24S8ToRGBA8(Surface& source, Surface& dest, const VideoCore::TextureBlit& blit); + bool ConvertDS24S8ToRGBA8(Surface& source, Surface& dest, const VideoCore::TextureCopy& copy); bool DepthToBuffer(Surface& source, vk::Buffer buffer, const VideoCore::BufferTextureCopy& copy); diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 4db96f370..f2ec5db0c 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -198,7 +198,7 @@ bool GraphicsPipeline::Build(bool fail_on_compile_required) { .pScissors = &scissor, }; - boost::container::static_vector dynamic_states = { + boost::container::static_vector dynamic_states = { vk::DynamicState::eViewport, vk::DynamicState::eScissor, vk::DynamicState::eStencilCompareMask, vk::DynamicState::eStencilWriteMask, vk::DynamicState::eStencilReference, vk::DynamicState::eBlendConstants, diff --git a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp index 5dd46609f..e6b78a297 100644 --- a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp @@ -283,12 +283,19 @@ void TextureRuntime::Finish() { } bool TextureRuntime::Reinterpret(Surface& source, Surface& dest, - const VideoCore::TextureBlit& blit) { + const VideoCore::TextureCopy& copy) { const PixelFormat src_format = source.pixel_format; const PixelFormat dst_format = dest.pixel_format; ASSERT_MSG(src_format != dst_format, "Reinterpretation with the same format is invalid"); + + if (!source.traits.needs_conversion && !dest.traits.needs_conversion && + source.type == dest.type) { + CopyTextures(source, dest, copy); + return true; + } + if (src_format == PixelFormat::D24S8 && dst_format == PixelFormat::RGBA8) { - blit_helper.ConvertDS24S8ToRGBA8(source, dest, blit); + blit_helper.ConvertDS24S8ToRGBA8(source, dest, copy); } else { LOG_WARNING(Render_Vulkan, "Unimplemented reinterpretation {} -> {}", VideoCore::PixelFormatAsString(src_format), diff --git a/src/video_core/renderer_vulkan/vk_texture_runtime.h b/src/video_core/renderer_vulkan/vk_texture_runtime.h index fd9b299e9..2bef63dab 100644 --- a/src/video_core/renderer_vulkan/vk_texture_runtime.h +++ b/src/video_core/renderer_vulkan/vk_texture_runtime.h @@ -68,7 +68,7 @@ public: VideoCore::StagingData FindStaging(u32 size, bool upload); /// Attempts to reinterpret a rectangle of source to another rectangle of dest - bool Reinterpret(Surface& source, Surface& dest, const VideoCore::TextureBlit& blit); + bool Reinterpret(Surface& source, Surface& dest, const VideoCore::TextureCopy& copy); /// Fills the rectangle of the texture with the clear value provided bool ClearTexture(Surface& surface, const VideoCore::TextureClear& clear);