mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	GPU: Be robust against nullptr addresses; properly reset busy bits in the trigger registers.
This commit is contained in:
		
							parent
							
								
									279e19732c
								
							
						
					
					
						commit
						93d66475d4
					
				
					 1 changed files with 34 additions and 27 deletions
				
			
		|  | @ -101,39 +101,43 @@ inline void Write(u32 addr, const T data) { | ||||||
|         const bool is_second_filler = (index != GPU_REG_INDEX(memory_fill_config[0].trigger)); |         const bool is_second_filler = (index != GPU_REG_INDEX(memory_fill_config[0].trigger)); | ||||||
|         auto& config = g_regs.memory_fill_config[is_second_filler]; |         auto& config = g_regs.memory_fill_config[is_second_filler]; | ||||||
| 
 | 
 | ||||||
|         if (config.address_start && config.trigger) { |         if (config.trigger) { | ||||||
|             u8* start = Memory::GetPhysicalPointer(config.GetStartAddress()); |             if (config.address_start) { // Some games pass invalid values here
 | ||||||
|             u8* end = Memory::GetPhysicalPointer(config.GetEndAddress()); |                 u8* start = Memory::GetPhysicalPointer(config.GetStartAddress()); | ||||||
|  |                 u8* end = Memory::GetPhysicalPointer(config.GetEndAddress()); | ||||||
| 
 | 
 | ||||||
|             if (config.fill_24bit) { |                 if (config.fill_24bit) { | ||||||
|                 // fill with 24-bit values
 |                     // fill with 24-bit values
 | ||||||
|                 for (u8* ptr = start; ptr < end; ptr += 3) { |                     for (u8* ptr = start; ptr < end; ptr += 3) { | ||||||
|                     ptr[0] = config.value_24bit_r; |                         ptr[0] = config.value_24bit_r; | ||||||
|                     ptr[1] = config.value_24bit_g; |                         ptr[1] = config.value_24bit_g; | ||||||
|                     ptr[2] = config.value_24bit_b; |                         ptr[2] = config.value_24bit_b; | ||||||
|  |                     } | ||||||
|  |                 } else if (config.fill_32bit) { | ||||||
|  |                     // fill with 32-bit values
 | ||||||
|  |                     for (u32* ptr = (u32*)start; ptr < (u32*)end; ++ptr) | ||||||
|  |                         *ptr = config.value_32bit; | ||||||
|  |                 } else { | ||||||
|  |                     // fill with 16-bit values
 | ||||||
|  |                     for (u16* ptr = (u16*)start; ptr < (u16*)end; ++ptr) | ||||||
|  |                         *ptr = config.value_16bit; | ||||||
|                 } |                 } | ||||||
|             } else if (config.fill_32bit) { | 
 | ||||||
|                 // fill with 32-bit values
 |                 LOG_TRACE(HW_GPU, "MemoryFill from 0x%08x to 0x%08x", config.GetStartAddress(), config.GetEndAddress()); | ||||||
|                 for (u32* ptr = (u32*)start; ptr < (u32*)end; ++ptr) | 
 | ||||||
|                     *ptr = config.value_32bit; |                 if (!is_second_filler) { | ||||||
|             } else { |                     GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC0); | ||||||
|                 // fill with 16-bit values
 |                 } else { | ||||||
|                 for (u16* ptr = (u16*)start; ptr < (u16*)end; ++ptr) |                     GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC1); | ||||||
|                     *ptr = config.value_16bit; |                 } | ||||||
|  | 
 | ||||||
|  |                 VideoCore::g_renderer->hw_rasterizer->NotifyFlush(config.GetStartAddress(), config.GetEndAddress() - config.GetStartAddress()); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             LOG_TRACE(HW_GPU, "MemoryFill from 0x%08x to 0x%08x", config.GetStartAddress(), config.GetEndAddress()); |             // Reset "trigger" flag and set the "finish" flag
 | ||||||
| 
 |             // NOTE: This was confirmed to happen on hardware even if "address_start" is zero.
 | ||||||
|             config.trigger = 0; |             config.trigger = 0; | ||||||
|             config.finished = 1; |             config.finished = 1; | ||||||
| 
 |  | ||||||
|             if (!is_second_filler) { |  | ||||||
|                 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC0); |  | ||||||
|             } else { |  | ||||||
|                 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC1); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             VideoCore::g_renderer->hw_rasterizer->NotifyFlush(config.GetStartAddress(), config.GetEndAddress() - config.GetStartAddress()); |  | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|  | @ -270,6 +274,7 @@ inline void Write(u32 addr, const T data) { | ||||||
|                       config.GetPhysicalOutputAddress(), output_width, output_height, |                       config.GetPhysicalOutputAddress(), output_width, output_height, | ||||||
|                       config.output_format.Value(), config.flags); |                       config.output_format.Value(), config.flags); | ||||||
| 
 | 
 | ||||||
|  |             g_regs.display_transfer_config.trigger = 0; | ||||||
|             GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PPF); |             GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PPF); | ||||||
| 
 | 
 | ||||||
|             VideoCore::g_renderer->hw_rasterizer->NotifyFlush(config.GetPhysicalOutputAddress(), output_size); |             VideoCore::g_renderer->hw_rasterizer->NotifyFlush(config.GetPhysicalOutputAddress(), output_size); | ||||||
|  | @ -285,6 +290,8 @@ inline void Write(u32 addr, const T data) { | ||||||
|         { |         { | ||||||
|             u32* buffer = (u32*)Memory::GetPhysicalPointer(config.GetPhysicalAddress()); |             u32* buffer = (u32*)Memory::GetPhysicalPointer(config.GetPhysicalAddress()); | ||||||
|             Pica::CommandProcessor::ProcessCommandList(buffer, config.size); |             Pica::CommandProcessor::ProcessCommandList(buffer, config.size); | ||||||
|  | 
 | ||||||
|  |             g_regs.command_processor_config.trigger = 0; | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue