mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	gl_rasterizer: call glTextureBarrier when an image is bound to both texture and framebuffer
This commit is contained in:
		
							parent
							
								
									610acf2828
								
							
						
					
					
						commit
						431fe444a9
					
				
					 1 changed files with 25 additions and 8 deletions
				
			
		|  | @ -47,6 +47,11 @@ RasterizerOpenGL::RasterizerOpenGL() | |||
|                     "Shadow might not be able to render because of unsupported OpenGL extensions."); | ||||
|     } | ||||
| 
 | ||||
|     if (!GLAD_GL_ARB_texture_barrier) { | ||||
|         LOG_WARNING(Render_OpenGL, | ||||
|                     "ARB_texture_barrier not supported. Some games might produce artifacts."); | ||||
|     } | ||||
| 
 | ||||
|     // Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0
 | ||||
|     state.clip_distance[0] = true; | ||||
| 
 | ||||
|  | @ -618,6 +623,13 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { | |||
|         uniform_block_data.dirty = true; | ||||
|     } | ||||
| 
 | ||||
|     bool need_texture_barrier = false; | ||||
|     auto CheckBarrier = [&need_texture_barrier, &color_surface](GLuint handle) { | ||||
|         if (color_surface && color_surface->texture.handle == handle) { | ||||
|             need_texture_barrier = true; | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     // Sync and bind the texture surfaces
 | ||||
|     const auto pica_textures = regs.texturing.GetTextures(); | ||||
|     for (unsigned texture_index = 0; texture_index < pica_textures.size(); ++texture_index) { | ||||
|  | @ -633,7 +645,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { | |||
| 
 | ||||
|                     Surface surface = res_cache.GetTextureSurface(texture); | ||||
|                     if (surface != nullptr) { | ||||
|                         state.image_shadow_texture_px = surface->texture.handle; | ||||
|                         CheckBarrier(state.image_shadow_texture_px = surface->texture.handle); | ||||
|                     } else { | ||||
|                         state.image_shadow_texture_px = 0; | ||||
|                     } | ||||
|  | @ -651,7 +663,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { | |||
|                         regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveX); | ||||
|                     surface = res_cache.GetTextureSurface(info); | ||||
|                     if (surface != nullptr) { | ||||
|                         state.image_shadow_texture_px = surface->texture.handle; | ||||
|                         CheckBarrier(state.image_shadow_texture_px = surface->texture.handle); | ||||
|                     } else { | ||||
|                         state.image_shadow_texture_px = 0; | ||||
|                     } | ||||
|  | @ -660,7 +672,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { | |||
|                         regs.texturing.GetCubePhysicalAddress(CubeFace::NegativeX); | ||||
|                     surface = res_cache.GetTextureSurface(info); | ||||
|                     if (surface != nullptr) { | ||||
|                         state.image_shadow_texture_nx = surface->texture.handle; | ||||
|                         CheckBarrier(state.image_shadow_texture_nx = surface->texture.handle); | ||||
|                     } else { | ||||
|                         state.image_shadow_texture_nx = 0; | ||||
|                     } | ||||
|  | @ -669,7 +681,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { | |||
|                         regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveY); | ||||
|                     surface = res_cache.GetTextureSurface(info); | ||||
|                     if (surface != nullptr) { | ||||
|                         state.image_shadow_texture_py = surface->texture.handle; | ||||
|                         CheckBarrier(state.image_shadow_texture_py = surface->texture.handle); | ||||
|                     } else { | ||||
|                         state.image_shadow_texture_py = 0; | ||||
|                     } | ||||
|  | @ -678,7 +690,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { | |||
|                         regs.texturing.GetCubePhysicalAddress(CubeFace::NegativeY); | ||||
|                     surface = res_cache.GetTextureSurface(info); | ||||
|                     if (surface != nullptr) { | ||||
|                         state.image_shadow_texture_ny = surface->texture.handle; | ||||
|                         CheckBarrier(state.image_shadow_texture_ny = surface->texture.handle); | ||||
|                     } else { | ||||
|                         state.image_shadow_texture_ny = 0; | ||||
|                     } | ||||
|  | @ -687,7 +699,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { | |||
|                         regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveZ); | ||||
|                     surface = res_cache.GetTextureSurface(info); | ||||
|                     if (surface != nullptr) { | ||||
|                         state.image_shadow_texture_pz = surface->texture.handle; | ||||
|                         CheckBarrier(state.image_shadow_texture_pz = surface->texture.handle); | ||||
|                     } else { | ||||
|                         state.image_shadow_texture_pz = 0; | ||||
|                     } | ||||
|  | @ -696,7 +708,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { | |||
|                         regs.texturing.GetCubePhysicalAddress(CubeFace::NegativeZ); | ||||
|                     surface = res_cache.GetTextureSurface(info); | ||||
|                     if (surface != nullptr) { | ||||
|                         state.image_shadow_texture_nz = surface->texture.handle; | ||||
|                         CheckBarrier(state.image_shadow_texture_nz = surface->texture.handle); | ||||
|                     } else { | ||||
|                         state.image_shadow_texture_nz = 0; | ||||
|                     } | ||||
|  | @ -727,7 +739,8 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { | |||
|             texture_samplers[texture_index].SyncWithConfig(texture.config); | ||||
|             Surface surface = res_cache.GetTextureSurface(texture); | ||||
|             if (surface != nullptr) { | ||||
|                 state.texture_units[texture_index].texture_2d = surface->texture.handle; | ||||
|                 CheckBarrier(state.texture_units[texture_index].texture_2d = | ||||
|                                  surface->texture.handle); | ||||
|             } else { | ||||
|                 // Can occur when texture addr is null or its memory is unmapped/invalid
 | ||||
|                 state.texture_units[texture_index].texture_2d = 0; | ||||
|  | @ -811,6 +824,10 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { | |||
|                         GL_TEXTURE_UPDATE_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT); | ||||
|     } | ||||
| 
 | ||||
|     if (need_texture_barrier && GLAD_GL_ARB_texture_barrier) { | ||||
|         glTextureBarrier(); | ||||
|     } | ||||
| 
 | ||||
|     // Mark framebuffer surfaces as dirty
 | ||||
|     MathUtil::Rectangle<u32> draw_rect_unscaled{ | ||||
|         draw_rect.left / res_scale, draw_rect.top / res_scale, draw_rect.right / res_scale, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue