mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Merge pull request #1391 from tfarley/hw-fb-sync-fix
hwrasterizer: Use proper cached framebuffer addr/size
This commit is contained in:
		
						commit
						69e2453649
					
				
					 2 changed files with 34 additions and 42 deletions
				
			
		|  | @ -36,7 +36,7 @@ static bool IsPassThroughTevStage(const Pica::Regs::TevStageConfig& stage) { | ||||||
|             stage.GetAlphaMultiplier() == 1); |             stage.GetAlphaMultiplier() == 1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RasterizerOpenGL::RasterizerOpenGL() : last_fb_color_addr(0), last_fb_depth_addr(0) { } | RasterizerOpenGL::RasterizerOpenGL() : cached_fb_color_addr(0), cached_fb_depth_addr(0) { } | ||||||
| RasterizerOpenGL::~RasterizerOpenGL() { } | RasterizerOpenGL::~RasterizerOpenGL() { } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::InitObjects() { | void RasterizerOpenGL::InitObjects() { | ||||||
|  | @ -169,16 +169,14 @@ void RasterizerOpenGL::DrawTriangles() { | ||||||
|     // Flush the resource cache at the current depth and color framebuffer addresses for render-to-texture
 |     // Flush the resource cache at the current depth and color framebuffer addresses for render-to-texture
 | ||||||
|     const auto& regs = Pica::g_state.regs; |     const auto& regs = Pica::g_state.regs; | ||||||
| 
 | 
 | ||||||
|     PAddr cur_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress(); |     u32 cached_fb_color_size = Pica::Regs::BytesPerColorPixel(fb_color_texture.format) | ||||||
|     u32 cur_fb_color_size = Pica::Regs::BytesPerColorPixel(regs.framebuffer.color_format) |                                * fb_color_texture.width * fb_color_texture.height; | ||||||
|                             * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); |  | ||||||
| 
 | 
 | ||||||
|     PAddr cur_fb_depth_addr = regs.framebuffer.GetDepthBufferPhysicalAddress(); |     u32 cached_fb_depth_size = Pica::Regs::BytesPerDepthPixel(fb_depth_texture.format) | ||||||
|     u32 cur_fb_depth_size = Pica::Regs::BytesPerDepthPixel(regs.framebuffer.depth_format) |                                * fb_depth_texture.width * fb_depth_texture.height; | ||||||
|                             * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); |  | ||||||
| 
 | 
 | ||||||
|     res_cache.InvalidateInRange(cur_fb_color_addr, cur_fb_color_size, true); |     res_cache.InvalidateInRange(cached_fb_color_addr, cached_fb_color_size, true); | ||||||
|     res_cache.InvalidateInRange(cur_fb_depth_addr, cur_fb_depth_size, true); |     res_cache.InvalidateInRange(cached_fb_depth_addr, cached_fb_depth_size, true); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::FlushFramebuffer() { | void RasterizerOpenGL::FlushFramebuffer() { | ||||||
|  | @ -291,38 +289,34 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { | ||||||
| void RasterizerOpenGL::FlushRegion(PAddr addr, u32 size) { | void RasterizerOpenGL::FlushRegion(PAddr addr, u32 size) { | ||||||
|     const auto& regs = Pica::g_state.regs; |     const auto& regs = Pica::g_state.regs; | ||||||
| 
 | 
 | ||||||
|     PAddr cur_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress(); |     u32 cached_fb_color_size = Pica::Regs::BytesPerColorPixel(fb_color_texture.format) | ||||||
|     u32 cur_fb_color_size = Pica::Regs::BytesPerColorPixel(regs.framebuffer.color_format) |                                * fb_color_texture.width * fb_color_texture.height; | ||||||
|                             * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); |  | ||||||
| 
 | 
 | ||||||
|     PAddr cur_fb_depth_addr = regs.framebuffer.GetDepthBufferPhysicalAddress(); |     u32 cached_fb_depth_size = Pica::Regs::BytesPerDepthPixel(fb_depth_texture.format) | ||||||
|     u32 cur_fb_depth_size = Pica::Regs::BytesPerDepthPixel(regs.framebuffer.depth_format) |                                * fb_depth_texture.width * fb_depth_texture.height; | ||||||
|                             * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); |  | ||||||
| 
 | 
 | ||||||
|     // If source memory region overlaps 3DS framebuffers, commit them before the copy happens
 |     // If source memory region overlaps 3DS framebuffers, commit them before the copy happens
 | ||||||
|     if (MathUtil::IntervalsIntersect(addr, size, cur_fb_color_addr, cur_fb_color_size)) |     if (MathUtil::IntervalsIntersect(addr, size, cached_fb_color_addr, cached_fb_color_size)) | ||||||
|         CommitColorBuffer(); |         CommitColorBuffer(); | ||||||
| 
 | 
 | ||||||
|     if (MathUtil::IntervalsIntersect(addr, size, cur_fb_depth_addr, cur_fb_depth_size)) |     if (MathUtil::IntervalsIntersect(addr, size, cached_fb_depth_addr, cached_fb_depth_size)) | ||||||
|         CommitDepthBuffer(); |         CommitDepthBuffer(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::InvalidateRegion(PAddr addr, u32 size) { | void RasterizerOpenGL::InvalidateRegion(PAddr addr, u32 size) { | ||||||
|     const auto& regs = Pica::g_state.regs; |     const auto& regs = Pica::g_state.regs; | ||||||
| 
 | 
 | ||||||
|     PAddr cur_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress(); |     u32 cached_fb_color_size = Pica::Regs::BytesPerColorPixel(fb_color_texture.format) | ||||||
|     u32 cur_fb_color_size = Pica::Regs::BytesPerColorPixel(regs.framebuffer.color_format) |                                * fb_color_texture.width * fb_color_texture.height; | ||||||
|                             * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); |  | ||||||
| 
 | 
 | ||||||
|     PAddr cur_fb_depth_addr = regs.framebuffer.GetDepthBufferPhysicalAddress(); |     u32 cached_fb_depth_size = Pica::Regs::BytesPerDepthPixel(fb_depth_texture.format) | ||||||
|     u32 cur_fb_depth_size = Pica::Regs::BytesPerDepthPixel(regs.framebuffer.depth_format) |                                * fb_depth_texture.width * fb_depth_texture.height; | ||||||
|                             * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); |  | ||||||
| 
 | 
 | ||||||
|     // If modified memory region overlaps 3DS framebuffers, reload their contents into OpenGL
 |     // If modified memory region overlaps 3DS framebuffers, reload their contents into OpenGL
 | ||||||
|     if (MathUtil::IntervalsIntersect(addr, size, cur_fb_color_addr, cur_fb_color_size)) |     if (MathUtil::IntervalsIntersect(addr, size, cached_fb_color_addr, cached_fb_color_size)) | ||||||
|         ReloadColorBuffer(); |         ReloadColorBuffer(); | ||||||
| 
 | 
 | ||||||
|     if (MathUtil::IntervalsIntersect(addr, size, cur_fb_depth_addr, cur_fb_depth_size)) |     if (MathUtil::IntervalsIntersect(addr, size, cached_fb_depth_addr, cached_fb_depth_size)) | ||||||
|         ReloadDepthBuffer(); |         ReloadDepthBuffer(); | ||||||
| 
 | 
 | ||||||
|     // Notify cache of flush in case the region touches a cached resource
 |     // Notify cache of flush in case the region touches a cached resource
 | ||||||
|  | @ -514,10 +508,10 @@ void RasterizerOpenGL::SetShader() { | ||||||
| void RasterizerOpenGL::SyncFramebuffer() { | void RasterizerOpenGL::SyncFramebuffer() { | ||||||
|     const auto& regs = Pica::g_state.regs; |     const auto& regs = Pica::g_state.regs; | ||||||
| 
 | 
 | ||||||
|     PAddr cur_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress(); |     PAddr new_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress(); | ||||||
|     Pica::Regs::ColorFormat new_fb_color_format = regs.framebuffer.color_format; |     Pica::Regs::ColorFormat new_fb_color_format = regs.framebuffer.color_format; | ||||||
| 
 | 
 | ||||||
|     PAddr cur_fb_depth_addr = regs.framebuffer.GetDepthBufferPhysicalAddress(); |     PAddr new_fb_depth_addr = regs.framebuffer.GetDepthBufferPhysicalAddress(); | ||||||
|     Pica::Regs::DepthFormat new_fb_depth_format = regs.framebuffer.depth_format; |     Pica::Regs::DepthFormat new_fb_depth_format = regs.framebuffer.depth_format; | ||||||
| 
 | 
 | ||||||
|     bool fb_size_changed = fb_color_texture.width != static_cast<GLsizei>(regs.framebuffer.GetWidth()) || |     bool fb_size_changed = fb_color_texture.width != static_cast<GLsizei>(regs.framebuffer.GetWidth()) || | ||||||
|  | @ -529,10 +523,10 @@ void RasterizerOpenGL::SyncFramebuffer() { | ||||||
|     bool depth_fb_prop_changed = fb_depth_texture.format != new_fb_depth_format || |     bool depth_fb_prop_changed = fb_depth_texture.format != new_fb_depth_format || | ||||||
|                                  fb_size_changed; |                                  fb_size_changed; | ||||||
| 
 | 
 | ||||||
|     bool color_fb_modified = last_fb_color_addr != cur_fb_color_addr || |     bool color_fb_modified = cached_fb_color_addr != new_fb_color_addr || | ||||||
|                              color_fb_prop_changed; |                              color_fb_prop_changed; | ||||||
| 
 | 
 | ||||||
|     bool depth_fb_modified = last_fb_depth_addr != cur_fb_depth_addr || |     bool depth_fb_modified = cached_fb_depth_addr != new_fb_depth_addr || | ||||||
|                              depth_fb_prop_changed; |                              depth_fb_prop_changed; | ||||||
| 
 | 
 | ||||||
|     // Commit if framebuffer modified in any way
 |     // Commit if framebuffer modified in any way
 | ||||||
|  | @ -572,13 +566,13 @@ void RasterizerOpenGL::SyncFramebuffer() { | ||||||
| 
 | 
 | ||||||
|     // Load buffer data again if fb modified in any way
 |     // Load buffer data again if fb modified in any way
 | ||||||
|     if (color_fb_modified) { |     if (color_fb_modified) { | ||||||
|         last_fb_color_addr = cur_fb_color_addr; |         cached_fb_color_addr = new_fb_color_addr; | ||||||
| 
 | 
 | ||||||
|         ReloadColorBuffer(); |         ReloadColorBuffer(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (depth_fb_modified) { |     if (depth_fb_modified) { | ||||||
|         last_fb_depth_addr = cur_fb_depth_addr; |         cached_fb_depth_addr = new_fb_depth_addr; | ||||||
| 
 | 
 | ||||||
|         ReloadDepthBuffer(); |         ReloadDepthBuffer(); | ||||||
|     } |     } | ||||||
|  | @ -723,7 +717,7 @@ void RasterizerOpenGL::SyncDrawState() { | ||||||
| MICROPROFILE_DEFINE(OpenGL_FramebufferReload, "OpenGL", "FB Reload", MP_RGB(70, 70, 200)); | MICROPROFILE_DEFINE(OpenGL_FramebufferReload, "OpenGL", "FB Reload", MP_RGB(70, 70, 200)); | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::ReloadColorBuffer() { | void RasterizerOpenGL::ReloadColorBuffer() { | ||||||
|     u8* color_buffer = Memory::GetPhysicalPointer(Pica::g_state.regs.framebuffer.GetColorBufferPhysicalAddress()); |     u8* color_buffer = Memory::GetPhysicalPointer(cached_fb_color_addr); | ||||||
| 
 | 
 | ||||||
|     if (color_buffer == nullptr) |     if (color_buffer == nullptr) | ||||||
|         return; |         return; | ||||||
|  | @ -758,13 +752,11 @@ void RasterizerOpenGL::ReloadColorBuffer() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::ReloadDepthBuffer() { | void RasterizerOpenGL::ReloadDepthBuffer() { | ||||||
|     PAddr depth_buffer_addr = Pica::g_state.regs.framebuffer.GetDepthBufferPhysicalAddress(); |     if (cached_fb_depth_addr == 0) | ||||||
| 
 |  | ||||||
|     if (depth_buffer_addr == 0) |  | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     // TODO: Appears to work, but double-check endianness of depth values and order of depth-stencil
 |     // TODO: Appears to work, but double-check endianness of depth values and order of depth-stencil
 | ||||||
|     u8* depth_buffer = Memory::GetPhysicalPointer(depth_buffer_addr); |     u8* depth_buffer = Memory::GetPhysicalPointer(cached_fb_depth_addr); | ||||||
| 
 | 
 | ||||||
|     if (depth_buffer == nullptr) |     if (depth_buffer == nullptr) | ||||||
|         return; |         return; | ||||||
|  | @ -827,8 +819,8 @@ Common::Profiling::TimingCategory buffer_commit_category("Framebuffer Commit"); | ||||||
| MICROPROFILE_DEFINE(OpenGL_FramebufferCommit, "OpenGL", "FB Commit", MP_RGB(70, 70, 200)); | MICROPROFILE_DEFINE(OpenGL_FramebufferCommit, "OpenGL", "FB Commit", MP_RGB(70, 70, 200)); | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::CommitColorBuffer() { | void RasterizerOpenGL::CommitColorBuffer() { | ||||||
|     if (last_fb_color_addr != 0) { |     if (cached_fb_color_addr != 0) { | ||||||
|         u8* color_buffer = Memory::GetPhysicalPointer(last_fb_color_addr); |         u8* color_buffer = Memory::GetPhysicalPointer(cached_fb_color_addr); | ||||||
| 
 | 
 | ||||||
|         if (color_buffer != nullptr) { |         if (color_buffer != nullptr) { | ||||||
|             Common::Profiling::ScopeTimer timer(buffer_commit_category); |             Common::Profiling::ScopeTimer timer(buffer_commit_category); | ||||||
|  | @ -863,9 +855,9 @@ void RasterizerOpenGL::CommitColorBuffer() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::CommitDepthBuffer() { | void RasterizerOpenGL::CommitDepthBuffer() { | ||||||
|     if (last_fb_depth_addr != 0) { |     if (cached_fb_depth_addr != 0) { | ||||||
|         // TODO: Output seems correct visually, but doesn't quite match sw renderer output. One of them is wrong.
 |         // TODO: Output seems correct visually, but doesn't quite match sw renderer output. One of them is wrong.
 | ||||||
|         u8* depth_buffer = Memory::GetPhysicalPointer(last_fb_depth_addr); |         u8* depth_buffer = Memory::GetPhysicalPointer(cached_fb_depth_addr); | ||||||
| 
 | 
 | ||||||
|         if (depth_buffer != nullptr) { |         if (depth_buffer != nullptr) { | ||||||
|             Common::Profiling::ScopeTimer timer(buffer_commit_category); |             Common::Profiling::ScopeTimer timer(buffer_commit_category); | ||||||
|  |  | ||||||
|  | @ -278,8 +278,8 @@ private: | ||||||
| 
 | 
 | ||||||
|     OpenGLState state; |     OpenGLState state; | ||||||
| 
 | 
 | ||||||
|     PAddr last_fb_color_addr; |     PAddr cached_fb_color_addr; | ||||||
|     PAddr last_fb_depth_addr; |     PAddr cached_fb_depth_addr; | ||||||
| 
 | 
 | ||||||
|     // Hardware rasterizer
 |     // Hardware rasterizer
 | ||||||
|     std::array<SamplerInfo, 3> texture_samplers; |     std::array<SamplerInfo, 3> texture_samplers; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue