mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Merge pull request #3788 from wwylele/shader-jit-breakc
shader/jit: implement breakc
This commit is contained in:
		
						commit
						2dac1a9590
					
				
					 2 changed files with 81 additions and 64 deletions
				
			
		|  | @ -68,7 +68,7 @@ const JitFunction instr_table[64] = { | |||
|     nullptr,                    // unknown
 | ||||
|     &JitShader::Compile_NOP,    // nop
 | ||||
|     &JitShader::Compile_END,    // end
 | ||||
|     nullptr,                   // break
 | ||||
|     &JitShader::Compile_BREAKC, // breakc
 | ||||
|     &JitShader::Compile_CALL,   // call
 | ||||
|     &JitShader::Compile_CALLC,  // callc
 | ||||
|     &JitShader::Compile_CALLU,  // callu
 | ||||
|  | @ -584,6 +584,14 @@ void JitShader::Compile_END(Instruction instr) { | |||
|     ret(); | ||||
| } | ||||
| 
 | ||||
| void JitShader::Compile_BREAKC(Instruction instr) { | ||||
|     Compile_Assert(looping, "BREAKC must be inside a LOOP"); | ||||
|     if (looping) { | ||||
|         Compile_EvaluateCondition(instr); | ||||
|         jnz(*loop_break_label); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void JitShader::Compile_CALL(Instruction instr) { | ||||
|     // Push offset of the return
 | ||||
|     push(qword, (instr.flow_control.dest_offset + instr.flow_control.num_instructions)); | ||||
|  | @ -727,11 +735,14 @@ void JitShader::Compile_LOOP(Instruction instr) { | |||
|     Label l_loop_start; | ||||
|     L(l_loop_start); | ||||
| 
 | ||||
|     loop_break_label = Xbyak::Label(); | ||||
|     Compile_Block(instr.flow_control.dest_offset + 1); | ||||
| 
 | ||||
|     add(LOOPCOUNT_REG, LOOPINC); // Increment LOOPCOUNT_REG by Z-component
 | ||||
|     sub(LOOPCOUNT, 1);           // Increment loop count by 1
 | ||||
|     jnz(l_loop_start);           // Loop if not equal
 | ||||
|     L(*loop_break_label); | ||||
|     loop_break_label = boost::none; | ||||
| 
 | ||||
|     looping = false; | ||||
| } | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ | |||
| #include <cstddef> | ||||
| #include <utility> | ||||
| #include <vector> | ||||
| #include <boost/optional.hpp> | ||||
| #include <nihstro/shader_bytecode.h> | ||||
| #include <xbyak.h> | ||||
| #include "common/bit_set.h" | ||||
|  | @ -58,6 +59,7 @@ public: | |||
|     void Compile_MOV(Instruction instr); | ||||
|     void Compile_NOP(Instruction instr); | ||||
|     void Compile_END(Instruction instr); | ||||
|     void Compile_BREAKC(Instruction instr); | ||||
|     void Compile_CALL(Instruction instr); | ||||
|     void Compile_CALLC(Instruction instr); | ||||
|     void Compile_CALLU(Instruction instr); | ||||
|  | @ -119,6 +121,10 @@ private: | |||
|     /// Mapping of Pica VS instructions to pointers in the emitted code
 | ||||
|     std::array<Xbyak::Label, MAX_PROGRAM_CODE_LENGTH> instruction_labels; | ||||
| 
 | ||||
|     /// Label pointing to the end of the current LOOP block. Used by the BREAKC instruction to break
 | ||||
|     /// out of the loop.
 | ||||
|     boost::optional<Xbyak::Label> loop_break_label; | ||||
| 
 | ||||
|     /// Offsets in code where a return needs to be inserted
 | ||||
|     std::vector<unsigned> return_offsets; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue