mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	GSP: Trigger GPU interrupts at more accurate locations.
This commit is contained in:
		
							parent
							
								
									e90b37b935
								
							
						
					
					
						commit
						f94d8f9603
					
				
					 3 changed files with 21 additions and 8 deletions
				
			
		|  | @ -173,6 +173,7 @@ static void RegisterInterruptRelayQueue(Service::Interface* self) { | |||
|  * Signals that the specified interrupt type has occurred to userland code | ||||
|  * @param interrupt_id ID of interrupt that is being signalled | ||||
|  * @todo This should probably take a thread_id parameter and only signal this thread? | ||||
|  * @todo This probably does not belong in the GSP module, instead move to video_core | ||||
|  */ | ||||
| void SignalInterrupt(InterruptId interrupt_id) { | ||||
|     if (0 == g_interrupt_event) { | ||||
|  | @ -211,6 +212,7 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | |||
|         memcpy(Memory::GetPointer(command.dma_request.dest_address), | ||||
|                Memory::GetPointer(command.dma_request.source_address), | ||||
|                command.dma_request.size); | ||||
|         SignalInterrupt(InterruptId::DMA); | ||||
|         break; | ||||
| 
 | ||||
|     // ctrulib homebrew sends all relevant command list data with this command,
 | ||||
|  | @ -219,13 +221,13 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | |||
|     case CommandId::SET_COMMAND_LIST_LAST: | ||||
|     { | ||||
|         auto& params = command.set_command_list_last; | ||||
| 
 | ||||
|         WriteGPURegister(GPU_REG_INDEX(command_processor_config.address), Memory::VirtualToPhysicalAddress(params.address) >> 3); | ||||
|         WriteGPURegister(GPU_REG_INDEX(command_processor_config.size), params.size); | ||||
| 
 | ||||
|         // TODO: Not sure if we are supposed to always write this .. seems to trigger processing though
 | ||||
|         WriteGPURegister(GPU_REG_INDEX(command_processor_config.trigger), 1); | ||||
| 
 | ||||
|         SignalInterrupt(InterruptId::P3D); | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|  | @ -243,6 +245,8 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | |||
|         WriteGPURegister(GPU_REG_INDEX(memory_fill_config[1].address_end), Memory::VirtualToPhysicalAddress(params.end2) >> 3); | ||||
|         WriteGPURegister(GPU_REG_INDEX(memory_fill_config[1].size), params.end2 - params.start2); | ||||
|         WriteGPURegister(GPU_REG_INDEX(memory_fill_config[1].value), params.value2); | ||||
| 
 | ||||
|         SignalInterrupt(InterruptId::PSC0); | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|  | @ -256,14 +260,9 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | |||
|         WriteGPURegister(GPU_REG_INDEX(display_transfer_config.flags), params.flags); | ||||
|         WriteGPURegister(GPU_REG_INDEX(display_transfer_config.trigger), 1); | ||||
| 
 | ||||
|         // TODO(bunnei): Signalling all of these interrupts here is totally wrong, but it seems to
 | ||||
|         // work well enough for running demos. Need to figure out how these all work and trigger
 | ||||
|         // them correctly.
 | ||||
|         SignalInterrupt(InterruptId::PSC0); | ||||
|         // TODO(bunnei): Determine if these interrupts should be signalled here.
 | ||||
|         SignalInterrupt(InterruptId::PSC1); | ||||
|         SignalInterrupt(InterruptId::PPF); | ||||
|         SignalInterrupt(InterruptId::P3D); | ||||
|         SignalInterrupt(InterruptId::DMA); | ||||
| 
 | ||||
|         // Update framebuffer information if requested
 | ||||
|         for (int screen_id = 0; screen_id < 2; ++screen_id) { | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ | |||
| #include "pica.h" | ||||
| #include "primitive_assembly.h" | ||||
| #include "vertex_shader.h" | ||||
| #include "core/hle/service/gsp_gpu.h" | ||||
| 
 | ||||
| #include "debug_utils/debug_utils.h" | ||||
| 
 | ||||
|  | @ -40,6 +41,11 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
|     DebugUtils::OnPicaRegWrite(id, registers[id]); | ||||
| 
 | ||||
|     switch(id) { | ||||
|         // Trigger IRQ
 | ||||
|         case PICA_REG_INDEX(trigger_irq): | ||||
|             GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::P3D); | ||||
|             return; | ||||
| 
 | ||||
|         // It seems like these trigger vertex rendering
 | ||||
|         case PICA_REG_INDEX(trigger_draw): | ||||
|         case PICA_REG_INDEX(trigger_draw_indexed): | ||||
|  |  | |||
|  | @ -45,10 +45,16 @@ struct Regs { | |||
| #define INSERT_PADDING_WORDS_HELPER2(x, y) INSERT_PADDING_WORDS_HELPER1(x, y) | ||||
| #define INSERT_PADDING_WORDS(num_words) u32 INSERT_PADDING_WORDS_HELPER2(pad, __LINE__)[(num_words)]; | ||||
| 
 | ||||
|     INSERT_PADDING_WORDS(0x41); | ||||
|     INSERT_PADDING_WORDS(0x10); | ||||
| 
 | ||||
|     u32 trigger_irq; | ||||
| 
 | ||||
|     INSERT_PADDING_WORDS(0x30); | ||||
| 
 | ||||
|     BitField<0, 24, u32> viewport_size_x; | ||||
| 
 | ||||
|     INSERT_PADDING_WORDS(0x1); | ||||
| 
 | ||||
|     BitField<0, 24, u32> viewport_size_y; | ||||
| 
 | ||||
|     INSERT_PADDING_WORDS(0x9); | ||||
|  | @ -544,6 +550,7 @@ struct Regs { | |||
|                     map.insert({i, #name + std::string("+") + std::to_string(i-PICA_REG_INDEX(name))});       \ | ||||
|             } while(false) | ||||
| 
 | ||||
|         ADD_FIELD(trigger_irq); | ||||
|         ADD_FIELD(viewport_size_x); | ||||
|         ADD_FIELD(viewport_size_y); | ||||
|         ADD_FIELD(viewport_depth_range); | ||||
|  | @ -607,6 +614,7 @@ private: | |||
| #ifndef _MSC_VER | ||||
| #define ASSERT_REG_POSITION(field_name, position) static_assert(offsetof(Regs, field_name) == position * 4, "Field "#field_name" has invalid position") | ||||
| 
 | ||||
| ASSERT_REG_POSITION(trigger_irq, 0x10); | ||||
| ASSERT_REG_POSITION(viewport_size_x, 0x41); | ||||
| ASSERT_REG_POSITION(viewport_size_y, 0x43); | ||||
| ASSERT_REG_POSITION(viewport_depth_range, 0x4d); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue