mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-10-31 06:46:40 +08:00 
			
		
		
		
	video_core: consistently account for resolution scaling when rendering
This commit is contained in:
		
							parent
							
								
									80de01a5b4
								
							
						
					
					
						commit
						453091f611
					
				| @ -747,16 +747,20 @@ std::optional<FramebufferTextureInfo> RasterizerOpenGL::AccelerateDisplay( | ||||
|     MICROPROFILE_SCOPE(OpenGL_CacheManagement); | ||||
| 
 | ||||
|     std::scoped_lock lock{texture_cache.mutex}; | ||||
|     ImageView* const image_view{ | ||||
|         texture_cache.TryFindFramebufferImageView(config, framebuffer_addr)}; | ||||
|     const auto [image_view, scaled] = | ||||
|         texture_cache.TryFindFramebufferImageView(config, framebuffer_addr); | ||||
|     if (!image_view) { | ||||
|         return {}; | ||||
|     } | ||||
| 
 | ||||
|     const auto& resolution = Settings::values.resolution_info; | ||||
| 
 | ||||
|     FramebufferTextureInfo info{}; | ||||
|     info.display_texture = image_view->Handle(Shader::TextureType::Color2D); | ||||
|     info.width = image_view->size.width; | ||||
|     info.height = image_view->size.height; | ||||
|     info.scaled_width = scaled ? resolution.ScaleUp(info.width) : info.width; | ||||
|     info.scaled_height = scaled ? resolution.ScaleUp(info.height) : info.height; | ||||
|     return info; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1051,6 +1051,10 @@ void Image::Scale(bool up_scale) { | ||||
|     state_tracker.NotifyScissor0(); | ||||
| } | ||||
| 
 | ||||
| bool Image::IsRescaled() const { | ||||
|     return True(flags & ImageFlagBits::Rescaled); | ||||
| } | ||||
| 
 | ||||
| bool Image::ScaleUp(bool ignore) { | ||||
|     const auto& resolution = runtime->resolution; | ||||
|     if (!resolution.active) { | ||||
|  | ||||
| @ -217,6 +217,8 @@ public: | ||||
|         return gl_type; | ||||
|     } | ||||
| 
 | ||||
|     bool IsRescaled() const; | ||||
| 
 | ||||
|     bool ScaleUp(bool ignore = false); | ||||
| 
 | ||||
|     bool ScaleDown(bool ignore = false); | ||||
|  | ||||
| @ -229,6 +229,8 @@ FramebufferTextureInfo RendererOpenGL::LoadFBToScreenInfo( | ||||
|     info.display_texture = framebuffer_texture.resource.handle; | ||||
|     info.width = framebuffer.width; | ||||
|     info.height = framebuffer.height; | ||||
|     info.scaled_width = framebuffer.width; | ||||
|     info.scaled_height = framebuffer.height; | ||||
| 
 | ||||
|     // TODO(Rodrigo): Read this from HLE
 | ||||
|     constexpr u32 block_height_log2 = 4; | ||||
| @ -476,25 +478,13 @@ void RendererOpenGL::DrawScreen(const Tegra::FramebufferConfig& framebuffer, | ||||
| 
 | ||||
|     if (anti_aliasing != Settings::AntiAliasing::None) { | ||||
|         glEnablei(GL_SCISSOR_TEST, 0); | ||||
|         auto viewport_width = info.width; | ||||
|         auto scissor_width = static_cast<u32>(crop.GetWidth()); | ||||
|         if (scissor_width <= 0) { | ||||
|             scissor_width = viewport_width; | ||||
|         } | ||||
|         auto viewport_height = info.height; | ||||
|         auto scissor_height = static_cast<u32>(crop.GetHeight()); | ||||
|         if (scissor_height <= 0) { | ||||
|             scissor_height = viewport_height; | ||||
|         } | ||||
| 
 | ||||
|         viewport_width = Settings::values.resolution_info.ScaleUp(viewport_width); | ||||
|         scissor_width = Settings::values.resolution_info.ScaleUp(scissor_width); | ||||
|         viewport_height = Settings::values.resolution_info.ScaleUp(viewport_height); | ||||
|         scissor_height = Settings::values.resolution_info.ScaleUp(scissor_height); | ||||
|         auto scissor_width = Settings::values.resolution_info.ScaleUp(framebuffer_texture.width); | ||||
|         auto viewport_width = static_cast<GLfloat>(scissor_width); | ||||
|         auto scissor_height = Settings::values.resolution_info.ScaleUp(framebuffer_texture.height); | ||||
|         auto viewport_height = static_cast<GLfloat>(scissor_height); | ||||
| 
 | ||||
|         glScissorIndexed(0, 0, 0, scissor_width, scissor_height); | ||||
|         glViewportIndexedf(0, 0.0f, 0.0f, static_cast<GLfloat>(viewport_width), | ||||
|                            static_cast<GLfloat>(viewport_height)); | ||||
|         glViewportIndexedf(0, 0.0f, 0.0f, viewport_width, viewport_height); | ||||
| 
 | ||||
|         glBindSampler(0, present_sampler.handle); | ||||
|         GLint old_read_fb; | ||||
| @ -557,10 +547,8 @@ void RendererOpenGL::DrawScreen(const Tegra::FramebufferConfig& framebuffer, | ||||
|             fsr->InitBuffers(); | ||||
|         } | ||||
| 
 | ||||
|         const auto fsr_input_width = Settings::values.resolution_info.ScaleUp(info.width); | ||||
|         const auto fsr_input_height = Settings::values.resolution_info.ScaleUp(info.height); | ||||
|         glBindSampler(0, present_sampler.handle); | ||||
|         fsr->Draw(program_manager, layout.screen, fsr_input_width, fsr_input_height, crop); | ||||
|         fsr->Draw(program_manager, layout.screen, info.scaled_width, info.scaled_height, crop); | ||||
|     } else { | ||||
|         if (fsr->AreBuffersInitialized()) { | ||||
|             fsr->ReleaseBuffers(); | ||||
|  | ||||
| @ -54,6 +54,8 @@ struct FramebufferTextureInfo { | ||||
|     GLuint display_texture{}; | ||||
|     u32 width; | ||||
|     u32 height; | ||||
|     u32 scaled_width; | ||||
|     u32 scaled_height; | ||||
| }; | ||||
| 
 | ||||
| class RendererOpenGL final : public VideoCore::RendererBase { | ||||
|  | ||||
| @ -152,6 +152,8 @@ void BlitScreen::Draw(RasterizerVulkan& rasterizer, const Tegra::FramebufferConf | ||||
|         framebuffer, framebuffer.address + framebuffer.offset, framebuffer.stride); | ||||
|     const u32 texture_width = texture_info ? texture_info->width : framebuffer.width; | ||||
|     const u32 texture_height = texture_info ? texture_info->height : framebuffer.height; | ||||
|     const u32 scaled_width = texture_info ? texture_info->scaled_width : texture_width; | ||||
|     const u32 scaled_height = texture_info ? texture_info->scaled_height : texture_height; | ||||
|     const bool use_accelerated = texture_info.has_value(); | ||||
| 
 | ||||
|     RefreshResources(framebuffer); | ||||
| @ -363,8 +365,8 @@ void BlitScreen::Draw(RasterizerVulkan& rasterizer, const Tegra::FramebufferConf | ||||
|     if (fsr) { | ||||
|         const auto crop_rect = Tegra::NormalizeCrop(framebuffer, texture_width, texture_height); | ||||
|         const VkExtent2D fsr_input_size{ | ||||
|             .width = Settings::values.resolution_info.ScaleUp(texture_width), | ||||
|             .height = Settings::values.resolution_info.ScaleUp(texture_height), | ||||
|             .width = scaled_width, | ||||
|             .height = scaled_height, | ||||
|         }; | ||||
|         VkImageView fsr_image_view = | ||||
|             fsr->Draw(scheduler, image_index, source_image_view, fsr_input_size, crop_rect); | ||||
|  | ||||
| @ -47,6 +47,8 @@ struct FramebufferTextureInfo { | ||||
|     VkImageView image_view{}; | ||||
|     u32 width{}; | ||||
|     u32 height{}; | ||||
|     u32 scaled_width{}; | ||||
|     u32 scaled_height{}; | ||||
| }; | ||||
| 
 | ||||
| class BlitScreen { | ||||
|  | ||||
| @ -788,18 +788,22 @@ std::optional<FramebufferTextureInfo> RasterizerVulkan::AccelerateDisplay( | ||||
|         return {}; | ||||
|     } | ||||
|     std::scoped_lock lock{texture_cache.mutex}; | ||||
|     ImageView* const image_view = | ||||
|     const auto [image_view, scaled] = | ||||
|         texture_cache.TryFindFramebufferImageView(config, framebuffer_addr); | ||||
|     if (!image_view) { | ||||
|         return {}; | ||||
|     } | ||||
|     query_cache.NotifySegment(false); | ||||
| 
 | ||||
|     const auto& resolution = Settings::values.resolution_info; | ||||
| 
 | ||||
|     FramebufferTextureInfo info{}; | ||||
|     info.image = image_view->ImageHandle(); | ||||
|     info.image_view = image_view->Handle(Shader::TextureType::Color2D); | ||||
|     info.width = image_view->size.width; | ||||
|     info.height = image_view->size.height; | ||||
|     info.scaled_width = scaled ? resolution.ScaleUp(info.width) : info.width; | ||||
|     info.scaled_height = scaled ? resolution.ScaleUp(info.height) : info.height; | ||||
|     return info; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -713,12 +713,12 @@ bool TextureCache<P>::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst, | ||||
| } | ||||
| 
 | ||||
| template <class P> | ||||
| typename P::ImageView* TextureCache<P>::TryFindFramebufferImageView( | ||||
| std::pair<typename P::ImageView*, bool> TextureCache<P>::TryFindFramebufferImageView( | ||||
|     const Tegra::FramebufferConfig& config, DAddr cpu_addr) { | ||||
|     // TODO: Properly implement this
 | ||||
|     const auto it = page_table.find(cpu_addr >> YUZU_PAGEBITS); | ||||
|     if (it == page_table.end()) { | ||||
|         return nullptr; | ||||
|         return {}; | ||||
|     } | ||||
|     const auto& image_map_ids = it->second; | ||||
|     boost::container::small_vector<ImageId, 4> valid_image_ids; | ||||
| @ -747,7 +747,8 @@ typename P::ImageView* TextureCache<P>::TryFindFramebufferImageView( | ||||
| 
 | ||||
|     const auto GetImageViewForFramebuffer = [&](ImageId image_id) { | ||||
|         const ImageViewInfo info{ImageViewType::e2D, view_format}; | ||||
|         return &slot_image_views[FindOrEmplaceImageView(image_id, info)]; | ||||
|         return std::make_pair(&slot_image_views[FindOrEmplaceImageView(image_id, info)], | ||||
|                               slot_images[image_id].IsRescaled()); | ||||
|     }; | ||||
| 
 | ||||
|     if (valid_image_ids.size() == 1) [[likely]] { | ||||
| @ -761,7 +762,7 @@ typename P::ImageView* TextureCache<P>::TryFindFramebufferImageView( | ||||
|         return GetImageViewForFramebuffer(*most_recent); | ||||
|     } | ||||
| 
 | ||||
|     return nullptr; | ||||
|     return {}; | ||||
| } | ||||
| 
 | ||||
| template <class P> | ||||
|  | ||||
| @ -212,8 +212,8 @@ public: | ||||
|                    const Tegra::Engines::Fermi2D::Config& copy); | ||||
| 
 | ||||
|     /// Try to find a cached image view in the given CPU address
 | ||||
|     [[nodiscard]] ImageView* TryFindFramebufferImageView(const Tegra::FramebufferConfig& config, | ||||
|                                                          DAddr cpu_addr); | ||||
|     [[nodiscard]] std::pair<ImageView*, bool> TryFindFramebufferImageView( | ||||
|         const Tegra::FramebufferConfig& config, DAddr cpu_addr); | ||||
| 
 | ||||
|     /// Return true when there are uncommitted images to be downloaded
 | ||||
|     [[nodiscard]] bool HasUncommittedFlushes() const noexcept; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user