mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	shader_ir: Implement BRX & BRA.CC
This commit is contained in:
		
							parent
							
								
									c218ae4b02
								
							
						
					
					
						commit
						8a6fc529a9
					
				@ -1367,6 +1367,20 @@ union Instruction {
 | 
			
		||||
        }
 | 
			
		||||
    } bra;
 | 
			
		||||
 | 
			
		||||
    union {
 | 
			
		||||
        BitField<20, 24, u64> target;
 | 
			
		||||
        BitField<5, 1, u64> constant_buffer;
 | 
			
		||||
 | 
			
		||||
        s32 GetBranchExtend() const {
 | 
			
		||||
            // Sign extend the branch target offset
 | 
			
		||||
            u32 mask = 1U << (24 - 1);
 | 
			
		||||
            u32 value = static_cast<u32>(target);
 | 
			
		||||
            // The branch offset is relative to the next instruction and is stored in bytes, so
 | 
			
		||||
            // divide it by the size of an instruction and add 1 to it.
 | 
			
		||||
            return static_cast<s32>((value ^ mask) - mask) / sizeof(Instruction) + 1;
 | 
			
		||||
        }
 | 
			
		||||
    } brx;
 | 
			
		||||
 | 
			
		||||
    union {
 | 
			
		||||
        BitField<39, 1, u64> emit; // EmitVertex
 | 
			
		||||
        BitField<40, 1, u64> cut;  // EndPrimitive
 | 
			
		||||
@ -1464,6 +1478,7 @@ public:
 | 
			
		||||
        BFE_IMM,
 | 
			
		||||
        BFI_IMM_R,
 | 
			
		||||
        BRA,
 | 
			
		||||
        BRX,
 | 
			
		||||
        PBK,
 | 
			
		||||
        LD_A,
 | 
			
		||||
        LD_L,
 | 
			
		||||
@ -1738,6 +1753,7 @@ private:
 | 
			
		||||
            INST("111000101001----", Id::SSY, Type::Flow, "SSY"),
 | 
			
		||||
            INST("111000101010----", Id::PBK, Type::Flow, "PBK"),
 | 
			
		||||
            INST("111000100100----", Id::BRA, Type::Flow, "BRA"),
 | 
			
		||||
            INST("111000100101----", Id::BRX, Type::Flow, "BRX"),
 | 
			
		||||
            INST("1111000011111---", Id::SYNC, Type::Flow, "SYNC"),
 | 
			
		||||
            INST("111000110100---", Id::BRK, Type::Flow, "BRK"),
 | 
			
		||||
            INST("111000110000----", Id::EXIT, Type::Flow, "EXIT"),
 | 
			
		||||
 | 
			
		||||
@ -1555,6 +1555,14 @@ private:
 | 
			
		||||
        return {};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string BranchIndirect(Operation operation) {
 | 
			
		||||
        const std::string op_a = VisitOperand(operation, 0, Type::Uint);
 | 
			
		||||
 | 
			
		||||
        code.AddLine("jmp_to = {};", op_a);
 | 
			
		||||
        code.AddLine("break;");
 | 
			
		||||
        return {};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string PushFlowStack(Operation operation) {
 | 
			
		||||
        const auto stack = std::get<MetaStackClass>(operation.GetMeta());
 | 
			
		||||
        const auto target = std::get_if<ImmediateNode>(&*operation[0]);
 | 
			
		||||
@ -1789,6 +1797,7 @@ private:
 | 
			
		||||
        &GLSLDecompiler::ImageStore,
 | 
			
		||||
 | 
			
		||||
        &GLSLDecompiler::Branch,
 | 
			
		||||
        &GLSLDecompiler::BranchIndirect,
 | 
			
		||||
        &GLSLDecompiler::PushFlowStack,
 | 
			
		||||
        &GLSLDecompiler::PopFlowStack,
 | 
			
		||||
        &GLSLDecompiler::Exit,
 | 
			
		||||
 | 
			
		||||
@ -949,6 +949,14 @@ private:
 | 
			
		||||
        return {};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Id BranchIndirect(Operation operation) {
 | 
			
		||||
        const Id op_a = VisitOperand<Type::Uint>(operation, 0);
 | 
			
		||||
 | 
			
		||||
        Emit(OpStore(jmp_to, op_a));
 | 
			
		||||
        BranchingOp([&]() { Emit(OpBranch(continue_label)); });
 | 
			
		||||
        return {};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Id PushFlowStack(Operation operation) {
 | 
			
		||||
        const auto target = std::get_if<ImmediateNode>(&*operation[0]);
 | 
			
		||||
        ASSERT(target);
 | 
			
		||||
@ -1334,6 +1342,7 @@ private:
 | 
			
		||||
        &SPIRVDecompiler::ImageStore,
 | 
			
		||||
 | 
			
		||||
        &SPIRVDecompiler::Branch,
 | 
			
		||||
        &SPIRVDecompiler::BranchIndirect,
 | 
			
		||||
        &SPIRVDecompiler::PushFlowStack,
 | 
			
		||||
        &SPIRVDecompiler::PopFlowStack,
 | 
			
		||||
        &SPIRVDecompiler::Exit,
 | 
			
		||||
 | 
			
		||||
@ -284,6 +284,9 @@ ParseResult ParseCode(CFGRebuildState& state, u32 address, ParseInfo& parse_info
 | 
			
		||||
            state.pbk_labels.emplace(offset, target);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        case OpCode::Id::BRX: {
 | 
			
		||||
            return ParseResult::AbnormalFlow;
 | 
			
		||||
        }
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -91,11 +91,45 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case OpCode::Id::BRA: {
 | 
			
		||||
        UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0,
 | 
			
		||||
                             "BRA with constant buffers are not implemented");
 | 
			
		||||
        Node branch;
 | 
			
		||||
        if (instr.bra.constant_buffer == 0) {
 | 
			
		||||
            const u32 target = pc + instr.bra.GetBranchTarget();
 | 
			
		||||
            branch = Operation(OperationCode::Branch, Immediate(target));
 | 
			
		||||
        } else {
 | 
			
		||||
            const u32 target = pc + 1;
 | 
			
		||||
            const Node op_a = GetConstBuffer(instr.cbuf36.index, instr.cbuf36.GetOffset());
 | 
			
		||||
            const Node convert = SignedOperation(OperationCode::IArithmeticShiftRight,
 | 
			
		||||
                                               true, PRECISE, op_a, Immediate(3));
 | 
			
		||||
            const Node operand = Operation(OperationCode::IAdd, PRECISE, convert, Immediate(target));
 | 
			
		||||
            branch = Operation(OperationCode::BranchIndirect, convert);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const u32 target = pc + instr.bra.GetBranchTarget();
 | 
			
		||||
        const Node branch = Operation(OperationCode::Branch, Immediate(target));
 | 
			
		||||
        const Tegra::Shader::ConditionCode cc = instr.flow_condition_code;
 | 
			
		||||
        if (cc != Tegra::Shader::ConditionCode::T) {
 | 
			
		||||
            bb.push_back(Conditional(GetConditionCode(cc), {branch}));
 | 
			
		||||
        } else {
 | 
			
		||||
            bb.push_back(branch);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case OpCode::Id::BRX: {
 | 
			
		||||
        Node operand;
 | 
			
		||||
        if (instr.brx.constant_buffer != 0) {
 | 
			
		||||
            const s32 target = pc + 1;
 | 
			
		||||
            const Node index = GetRegister(instr.gpr8);
 | 
			
		||||
            const Node op_a =
 | 
			
		||||
                GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.GetOffset() + 0, index);
 | 
			
		||||
            const Node convert = SignedOperation(OperationCode::IArithmeticShiftRight,
 | 
			
		||||
                                               true, PRECISE, op_a, Immediate(3));
 | 
			
		||||
            operand = Operation(OperationCode::IAdd, PRECISE, convert, Immediate(target));
 | 
			
		||||
        } else {
 | 
			
		||||
            const s32 target = pc + instr.brx.GetBranchExtend();
 | 
			
		||||
            const Node op_a = GetRegister(instr.gpr8);
 | 
			
		||||
            const Node convert = SignedOperation(OperationCode::IArithmeticShiftRight,
 | 
			
		||||
                                               true, PRECISE, op_a, Immediate(3));
 | 
			
		||||
            operand = Operation(OperationCode::IAdd, PRECISE, convert, Immediate(target));
 | 
			
		||||
        }
 | 
			
		||||
        const Node branch = Operation(OperationCode::BranchIndirect, operand);
 | 
			
		||||
 | 
			
		||||
        const Tegra::Shader::ConditionCode cc = instr.flow_condition_code;
 | 
			
		||||
        if (cc != Tegra::Shader::ConditionCode::T) {
 | 
			
		||||
 | 
			
		||||
@ -149,6 +149,7 @@ enum class OperationCode {
 | 
			
		||||
    ImageStore, /// (MetaImage, float[N] coords) -> void
 | 
			
		||||
 | 
			
		||||
    Branch,        /// (uint branch_target) -> void
 | 
			
		||||
    BranchIndirect,/// (uint branch_target) -> void
 | 
			
		||||
    PushFlowStack, /// (uint branch_target) -> void
 | 
			
		||||
    PopFlowStack,  /// () -> void
 | 
			
		||||
    Exit,          /// () -> void
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user