ShaderGen: Implemented predicated instruction execution.
Each predicated instruction will be wrapped in an `if (predicate) { instruction_body; }` in the GLSL, where `predicate` is one of the predicate boolean variables previously set by fsetp.
			
			
This commit is contained in:
		
							parent
							
								
									0a5e01b710
								
							
						
					
					
						commit
						c3a8ea76f1
					
				@ -331,7 +331,11 @@ union Instruction {
 | 
			
		||||
    OpCode opcode;
 | 
			
		||||
    BitField<0, 8, Register> gpr0;
 | 
			
		||||
    BitField<8, 8, Register> gpr8;
 | 
			
		||||
    BitField<16, 4, Pred> pred;
 | 
			
		||||
    union {
 | 
			
		||||
        BitField<16, 4, Pred> full_pred;
 | 
			
		||||
        BitField<16, 3, u64> pred_index;
 | 
			
		||||
    } pred;
 | 
			
		||||
    BitField<19, 1, u64> negate_pred;
 | 
			
		||||
    BitField<20, 8, Register> gpr20;
 | 
			
		||||
    BitField<20, 7, SubOp> sub_op;
 | 
			
		||||
    BitField<28, 8, Register> gpr28;
 | 
			
		||||
 | 
			
		||||
@ -293,6 +293,25 @@ private:
 | 
			
		||||
        declr_predicates.insert(std::move(variable));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Returns the condition to use in the 'if' for a predicated instruction.
 | 
			
		||||
     * @param instr Instruction to generate the if condition for.
 | 
			
		||||
     * @returns string containing the predicate condition.
 | 
			
		||||
     */
 | 
			
		||||
    std::string GetPredicateCondition(Instruction instr) const {
 | 
			
		||||
        using Tegra::Shader::Pred;
 | 
			
		||||
        ASSERT(instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex));
 | 
			
		||||
 | 
			
		||||
        std::string variable =
 | 
			
		||||
            'p' + std::to_string(static_cast<u64>(instr.pred.pred_index.Value()));
 | 
			
		||||
 | 
			
		||||
        if (instr.negate_pred) {
 | 
			
		||||
            return "!(" + variable + ')';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return variable;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Returns whether the instruction at the specified offset is a 'sched' instruction.
 | 
			
		||||
     * Sched instructions always appear before a sequence of 3 instructions.
 | 
			
		||||
@ -320,6 +339,16 @@ private:
 | 
			
		||||
 | 
			
		||||
        shader.AddLine("// " + std::to_string(offset) + ": " + OpCode::GetInfo(instr.opcode).name);
 | 
			
		||||
 | 
			
		||||
        using Tegra::Shader::Pred;
 | 
			
		||||
        ASSERT_MSG(instr.pred.full_pred != Pred::NeverExecute,
 | 
			
		||||
                   "NeverExecute predicate not implemented");
 | 
			
		||||
 | 
			
		||||
        if (instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) {
 | 
			
		||||
            shader.AddLine("if (" + GetPredicateCondition(instr) + ')');
 | 
			
		||||
            shader.AddLine('{');
 | 
			
		||||
            ++shader.scope;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch (OpCode::GetInfo(instr.opcode).type) {
 | 
			
		||||
        case OpCode::Type::Arithmetic: {
 | 
			
		||||
            std::string dest = GetRegister(instr.gpr0);
 | 
			
		||||
@ -559,6 +588,12 @@ private:
 | 
			
		||||
        }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Close the predicate condition scope.
 | 
			
		||||
        if (instr.pred != Pred::UnusedIndex) {
 | 
			
		||||
            --shader.scope;
 | 
			
		||||
            shader.AddLine('}');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return offset + 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user