mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	video_core: Correct shader interpeter address register handling. (#6910)
This commit is contained in:
		
							parent
							
								
									61cf550d0c
								
							
						
					
					
						commit
						df57012c50
					
				
					 1 changed files with 41 additions and 33 deletions
				
			
		|  | @ -112,8 +112,9 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData | |||
|     const auto& swizzle_data = setup.swizzle_data; | ||||
|     const auto& program_code = setup.program_code; | ||||
| 
 | ||||
|     // Placeholder for invalid inputs
 | ||||
|     static f24 dummy_vec4_float24[4]; | ||||
|     // Constants for handling invalid inputs
 | ||||
|     static f24 dummy_vec4_float24_zeros[4] = {f24::Zero(), f24::Zero(), f24::Zero(), f24::Zero()}; | ||||
|     static f24 dummy_vec4_float24_ones[4] = {f24::One(), f24::One(), f24::One(), f24::One()}; | ||||
| 
 | ||||
|     u32 iteration = 0; | ||||
|     bool should_stop = false; | ||||
|  | @ -130,19 +131,33 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData | |||
| 
 | ||||
|         debug_data.max_offset = std::max<u32>(debug_data.max_offset, 1 + program_counter); | ||||
| 
 | ||||
|         auto LookupSourceRegister = [&](const SourceRegister& source_reg) -> const f24* { | ||||
|         auto LookupSourceRegister = [&](const SourceRegister& source_reg, | ||||
|                                         int address_register_index) -> const f24* { | ||||
|             int index = source_reg.GetIndex(); | ||||
|             switch (source_reg.GetRegisterType()) { | ||||
|             case RegisterType::Input: | ||||
|                 return &state.registers.input[source_reg.GetIndex()].x; | ||||
|                 return &state.registers.input[index].x; | ||||
| 
 | ||||
|             case RegisterType::Temporary: | ||||
|                 return &state.registers.temporary[source_reg.GetIndex()].x; | ||||
|                 return &state.registers.temporary[index].x; | ||||
| 
 | ||||
|             case RegisterType::FloatUniform: | ||||
|                 return &uniforms.f[source_reg.GetIndex()].x; | ||||
|                 if (address_register_index != 0) { | ||||
|                     int offset = state.address_registers[address_register_index - 1]; | ||||
|                     if (offset < std::numeric_limits<s8>::min() || | ||||
|                         offset > std::numeric_limits<s8>::max()) [[unlikely]] { | ||||
|                         offset = 0; | ||||
|                     } | ||||
|                     index = (index + offset) & 0x7F; | ||||
|                     // If the index is above 96, the result is all one.
 | ||||
|                     if (index >= 96) [[unlikely]] { | ||||
|                         return dummy_vec4_float24_ones; | ||||
|                     } | ||||
|                 } | ||||
|                 return &uniforms.f[index].x; | ||||
| 
 | ||||
|             default: | ||||
|                 return dummy_vec4_float24; | ||||
|                 return dummy_vec4_float24_zeros; | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|  | @ -151,18 +166,15 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData | |||
|             const bool is_inverted = | ||||
|                 (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed)); | ||||
| 
 | ||||
|             const int address_offset = | ||||
|                 (instr.common.address_register_index == 0) | ||||
|                     ? 0 | ||||
|                     : state.address_registers[instr.common.address_register_index - 1]; | ||||
|             const f24* src1_ = | ||||
|                 LookupSourceRegister(instr.common.GetSrc1(is_inverted), | ||||
|                                      !is_inverted * instr.common.address_register_index); | ||||
|             const f24* src2_ = | ||||
|                 LookupSourceRegister(instr.common.GetSrc2(is_inverted), | ||||
|                                      is_inverted * instr.common.address_register_index); | ||||
| 
 | ||||
|             const f24* src1_ = LookupSourceRegister(instr.common.GetSrc1(is_inverted) + | ||||
|                                                     (is_inverted ? 0 : address_offset)); | ||||
|             const f24* src2_ = LookupSourceRegister(instr.common.GetSrc2(is_inverted) + | ||||
|                                                     (is_inverted ? address_offset : 0)); | ||||
| 
 | ||||
|             const bool negate_src1 = ((bool)swizzle.negate_src1 != false); | ||||
|             const bool negate_src2 = ((bool)swizzle.negate_src2 != false); | ||||
|             const bool negate_src1 = swizzle.negate_src1.Value() != 0; | ||||
|             const bool negate_src2 = swizzle.negate_src2.Value() != 0; | ||||
| 
 | ||||
|             f24 src1[4] = { | ||||
|                 src1_[(int)swizzle.src1_selector_0.Value()], | ||||
|  | @ -193,7 +205,7 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData | |||
|                             ? &state.registers.output[instr.common.dest.Value().GetIndex()][0] | ||||
|                         : (instr.common.dest.Value() < 0x20) | ||||
|                             ? &state.registers.temporary[instr.common.dest.Value().GetIndex()][0] | ||||
|                             : dummy_vec4_float24; | ||||
|                             : dummy_vec4_float24_zeros; | ||||
| 
 | ||||
|             debug_data.max_opdesc_id = | ||||
|                 std::max<u32>(debug_data.max_opdesc_id, 1 + instr.common.operand_desc_id); | ||||
|  | @ -476,20 +488,16 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData | |||
| 
 | ||||
|                 bool is_inverted = (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI); | ||||
| 
 | ||||
|                 const int address_offset = | ||||
|                     (instr.mad.address_register_index == 0) | ||||
|                         ? 0 | ||||
|                         : state.address_registers[instr.mad.address_register_index - 1]; | ||||
|                 const f24* src1_ = LookupSourceRegister(instr.mad.GetSrc1(is_inverted), 0); | ||||
|                 const f24* src2_ = | ||||
|                     LookupSourceRegister(instr.mad.GetSrc2(is_inverted), | ||||
|                                          !is_inverted * instr.mad.address_register_index); | ||||
|                 const f24* src3_ = LookupSourceRegister( | ||||
|                     instr.mad.GetSrc3(is_inverted), is_inverted * instr.mad.address_register_index); | ||||
| 
 | ||||
|                 const f24* src1_ = LookupSourceRegister(instr.mad.GetSrc1(is_inverted)); | ||||
|                 const f24* src2_ = LookupSourceRegister(instr.mad.GetSrc2(is_inverted) + | ||||
|                                                         (!is_inverted * address_offset)); | ||||
|                 const f24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted) + | ||||
|                                                         (is_inverted * address_offset)); | ||||
| 
 | ||||
|                 const bool negate_src1 = ((bool)mad_swizzle.negate_src1 != false); | ||||
|                 const bool negate_src2 = ((bool)mad_swizzle.negate_src2 != false); | ||||
|                 const bool negate_src3 = ((bool)mad_swizzle.negate_src3 != false); | ||||
|                 const bool negate_src1 = mad_swizzle.negate_src1.Value() != 0; | ||||
|                 const bool negate_src2 = mad_swizzle.negate_src2.Value() != 0; | ||||
|                 const bool negate_src3 = mad_swizzle.negate_src3.Value() != 0; | ||||
| 
 | ||||
|                 f24 src1[4] = { | ||||
|                     src1_[(int)mad_swizzle.src1_selector_0.Value()], | ||||
|  | @ -532,7 +540,7 @@ static void RunInterpreter(const ShaderSetup& setup, UnitState& state, DebugData | |||
|                                 ? &state.registers.output[instr.mad.dest.Value().GetIndex()][0] | ||||
|                             : (instr.mad.dest.Value() < 0x20) | ||||
|                                 ? &state.registers.temporary[instr.mad.dest.Value().GetIndex()][0] | ||||
|                                 : dummy_vec4_float24; | ||||
|                                 : dummy_vec4_float24_zeros; | ||||
| 
 | ||||
|                 Record<DebugDataRecord::SRC1>(debug_data, iteration, src1); | ||||
|                 Record<DebugDataRecord::SRC2>(debug_data, iteration, src2); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue