mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	GPU: Partially implemented the shader BRA instruction.
This commit is contained in:
		
							parent
							
								
									06c72b4fcf
								
							
						
					
					
						commit
						b481d8a00d
					
				@ -288,6 +288,19 @@ union Instruction {
 | 
			
		||||
        }
 | 
			
		||||
    } texs;
 | 
			
		||||
 | 
			
		||||
    union {
 | 
			
		||||
        BitField<20, 5, u64> target;
 | 
			
		||||
        BitField<5, 1, u64> constant_buffer;
 | 
			
		||||
 | 
			
		||||
        s32 GetBranchTarget() const {
 | 
			
		||||
            // Sign extend the branch target offset
 | 
			
		||||
            u32 mask = 1U << (5 - 1);
 | 
			
		||||
            u32 value = static_cast<u32>(target);
 | 
			
		||||
            // The branch offset is relative to the next instruction, so add 1 to it.
 | 
			
		||||
            return static_cast<s32>((value ^ mask) - mask) + 1;
 | 
			
		||||
        }
 | 
			
		||||
    } bra;
 | 
			
		||||
 | 
			
		||||
    BitField<61, 1, u64> is_b_imm;
 | 
			
		||||
    BitField<60, 1, u64> is_b_gpr;
 | 
			
		||||
    BitField<59, 1, u64> is_c_gpr;
 | 
			
		||||
 | 
			
		||||
@ -88,6 +88,20 @@ private:
 | 
			
		||||
        return *subroutines.insert(std::move(subroutine)).first;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Merges exit method of two parallel branches.
 | 
			
		||||
    static ExitMethod ParallelExit(ExitMethod a, ExitMethod b) {
 | 
			
		||||
        if (a == ExitMethod::Undetermined) {
 | 
			
		||||
            return b;
 | 
			
		||||
        }
 | 
			
		||||
        if (b == ExitMethod::Undetermined) {
 | 
			
		||||
            return a;
 | 
			
		||||
        }
 | 
			
		||||
        if (a == b) {
 | 
			
		||||
            return a;
 | 
			
		||||
        }
 | 
			
		||||
        return ExitMethod::Conditional;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Scans a range of code for labels and determines the exit method.
 | 
			
		||||
    ExitMethod Scan(u32 begin, u32 end, std::set<u32>& labels) {
 | 
			
		||||
        auto [iter, inserted] =
 | 
			
		||||
@ -97,11 +111,19 @@ private:
 | 
			
		||||
            return exit_method;
 | 
			
		||||
 | 
			
		||||
        for (u32 offset = begin; offset != end && offset != PROGRAM_END; ++offset) {
 | 
			
		||||
            if (const auto opcode = OpCode::Decode({program_code[offset]})) {
 | 
			
		||||
            const Instruction instr = {program_code[offset]};
 | 
			
		||||
            if (const auto opcode = OpCode::Decode(instr)) {
 | 
			
		||||
                switch (opcode->GetId()) {
 | 
			
		||||
                case OpCode::Id::EXIT: {
 | 
			
		||||
                    return exit_method = ExitMethod::AlwaysEnd;
 | 
			
		||||
                }
 | 
			
		||||
                case OpCode::Id::BRA: {
 | 
			
		||||
                    u32 target = offset + instr.bra.GetBranchTarget();
 | 
			
		||||
                    labels.insert(target);
 | 
			
		||||
                    ExitMethod no_jmp = Scan(offset + 1, end, labels);
 | 
			
		||||
                    ExitMethod jmp = Scan(target, end, labels);
 | 
			
		||||
                    return exit_method = ParallelExit(no_jmp, jmp);
 | 
			
		||||
                }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@ -1081,6 +1103,13 @@ private:
 | 
			
		||||
                shader.AddLine("discard;");
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case OpCode::Id::BRA: {
 | 
			
		||||
                ASSERT_MSG(instr.bra.constant_buffer == 0,
 | 
			
		||||
                           "BRA with constant buffers are not implemented");
 | 
			
		||||
                u32 target = offset + instr.bra.GetBranchTarget();
 | 
			
		||||
                shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }");
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case OpCode::Id::IPA: {
 | 
			
		||||
                const auto& attribute = instr.attribute.fmt28;
 | 
			
		||||
                regs.SetRegisterToInputAttibute(instr.gpr0, attribute.element, attribute.index);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user