diff --git a/README.md b/README.md index 34af1bd09..cbb675d1d 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 2208. +This is the source code for early-access 2210. ## Legal Notice diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 2f7d98d8b..e560111c3 100755 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -522,6 +522,12 @@ void TextureCacheRuntime::CopyImage(Image& dst_image, Image& src_image, } } +void TextureCacheRuntime::ConvertImage(Image& dst, Image& src, + std::span copies) { + LOG_DEBUG(Render_OpenGL, "Converting {} to {}", src.info.format, dst.info.format); + format_conversion_pass.ConvertImage(dst, src, copies); +} + bool TextureCacheRuntime::CanImageBeCopied(const Image& dst, const Image& src) { if (dst.info.type == ImageType::e3D && dst.info.format == PixelFormat::BC4_UNORM) { return false; @@ -538,7 +544,7 @@ void TextureCacheRuntime::EmulateCopyImage(Image& dst, Image& src, ASSERT(src.info.type == ImageType::e3D); util_shaders.CopyBC4(dst, src, copies); } else if (IsPixelFormatBGR(dst.info.format) || IsPixelFormatBGR(src.info.format)) { - bgr_copy_pass.CopyBGR(dst, src, copies); + format_conversion_pass.ConvertImage(dst, src, copies); } else { UNREACHABLE(); } @@ -1286,35 +1292,37 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span copies) { - static constexpr VideoCommon::Offset3D zero_offset{0, 0, 0}; +void FormatConversionPass::ConvertImage(Image& dst_image, Image& src_image, + std::span copies) { + const GLenum dst_target = ImageTarget(dst_image.info); + const GLenum src_target = ImageTarget(src_image.info); const u32 img_bpp = BytesPerBlock(src_image.info.format); for (const ImageCopy& copy : copies) { - ASSERT(copy.src_offset == zero_offset); - ASSERT(copy.dst_offset == zero_offset); - const u32 num_src_layers = static_cast(copy.src_subresource.num_layers); - const u32 copy_size = copy.extent.width * copy.extent.height * num_src_layers * img_bpp; - if (bgr_pbo_size < copy_size) { - bgr_pbo.Create(); - bgr_pbo_size = copy_size; - glNamedBufferData(bgr_pbo.handle, bgr_pbo_size, nullptr, GL_STREAM_COPY); + const auto src_origin = MakeCopyOrigin(copy.src_offset, copy.src_subresource, src_target); + const auto dst_origin = MakeCopyOrigin(copy.dst_offset, copy.dst_subresource, dst_target); + const auto region = MakeCopyRegion(copy.extent, copy.dst_subresource, dst_target); + const u32 copy_size = region.width * region.height * region.depth * img_bpp; + if (pbo_size < copy_size) { + intermediate_pbo.Create(); + pbo_size = copy_size; + glNamedBufferData(intermediate_pbo.handle, pbo_size, nullptr, GL_STREAM_COPY); } // Copy from source to PBO glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, copy.extent.width); - glBindBuffer(GL_PIXEL_PACK_BUFFER, bgr_pbo.handle); - glGetTextureSubImage(src_image.Handle(), 0, 0, 0, 0, copy.extent.width, copy.extent.height, - num_src_layers, src_image.GlFormat(), src_image.GlType(), - static_cast(bgr_pbo_size), nullptr); + glBindBuffer(GL_PIXEL_PACK_BUFFER, intermediate_pbo.handle); + glGetTextureSubImage(src_image.Handle(), src_origin.level, src_origin.x, src_origin.y, + src_origin.z, region.width, region.height, region.depth, + src_image.GlFormat(), src_image.GlType(), + static_cast(pbo_size), nullptr); // Copy from PBO to destination in desired GL format glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ROW_LENGTH, copy.extent.width); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, bgr_pbo.handle); - glTextureSubImage3D(dst_image.Handle(), 0, 0, 0, 0, copy.extent.width, copy.extent.height, - copy.dst_subresource.num_layers, dst_image.GlFormat(), - dst_image.GlType(), nullptr); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, intermediate_pbo.handle); + glTextureSubImage3D(dst_image.Handle(), dst_origin.level, dst_origin.x, dst_origin.y, + dst_origin.z, region.width, region.height, region.depth, + dst_image.GlFormat(), dst_image.GlType(), nullptr); } } diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 1bb762568..578f8d523 100755 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h @@ -52,17 +52,17 @@ struct FormatProperties { bool is_compressed; }; -class BGRCopyPass { +class FormatConversionPass { public: - BGRCopyPass() = default; - ~BGRCopyPass() = default; + FormatConversionPass() = default; + ~FormatConversionPass() = default; - void CopyBGR(Image& dst_image, Image& src_image, - std::span copies); + void ConvertImage(Image& dst_image, Image& src_image, + std::span copies); private: - OGLBuffer bgr_pbo; - size_t bgr_pbo_size{}; + OGLBuffer intermediate_pbo; + size_t pbo_size{}; }; class TextureCacheRuntime { @@ -86,6 +86,8 @@ public: void CopyImage(Image& dst, Image& src, std::span copies); + void ConvertImage(Image& dst, Image& src, std::span copies); + void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view, bool rescaled) { UNIMPLEMENTED(); } @@ -144,7 +146,7 @@ private: const Device& device; StateTracker& state_tracker; UtilShaders util_shaders; - BGRCopyPass bgr_copy_pass; + FormatConversionPass format_conversion_pass; std::array, 3> format_properties; bool has_broken_texture_view_formats = false; @@ -336,6 +338,7 @@ struct TextureCacheParams { static constexpr bool FRAMEBUFFER_BLITS = true; static constexpr bool HAS_EMULATED_COPIES = true; static constexpr bool HAS_DEVICE_MEMORY_INFO = true; + static constexpr bool HAS_PIXEL_FORMAT_CONVERSIONS = true; using Runtime = OpenGL::TextureCacheRuntime; using Image = OpenGL::Image; diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index ff28b4e96..f5f8f9a74 100755 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -316,6 +316,7 @@ struct TextureCacheParams { static constexpr bool FRAMEBUFFER_BLITS = false; static constexpr bool HAS_EMULATED_COPIES = false; static constexpr bool HAS_DEVICE_MEMORY_INFO = true; + static constexpr bool HAS_PIXEL_FORMAT_CONVERSIONS = false; using Runtime = Vulkan::TextureCacheRuntime; using Image = Vulkan::Image; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 4d2874bf2..241f71a91 100755 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -1759,6 +1759,9 @@ void TextureCache

::CopyImage(ImageId dst_id, ImageId src_id, std::vector