mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	gl_shader_decompiler: Add support for TEXS instruction.
This commit is contained in:
		
							parent
							
								
									5ba71369ac
								
							
						
					
					
						commit
						8b4443c966
					
				@ -16,10 +16,6 @@ struct Register {
 | 
			
		||||
 | 
			
		||||
    constexpr Register(u64 value) : value(value) {}
 | 
			
		||||
 | 
			
		||||
    constexpr u64 GetIndex() const {
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    constexpr operator u64() const {
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
@ -71,6 +67,19 @@ union Attribute {
 | 
			
		||||
    u64 value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
union Sampler {
 | 
			
		||||
    Sampler() = default;
 | 
			
		||||
 | 
			
		||||
    constexpr Sampler(u64 value) : value(value) {}
 | 
			
		||||
 | 
			
		||||
    enum class Index : u64 {
 | 
			
		||||
        Sampler_0 = 8,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    BitField<36, 13, Index> index;
 | 
			
		||||
    u64 value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
union Uniform {
 | 
			
		||||
    BitField<20, 14, u64> offset;
 | 
			
		||||
    BitField<34, 5, u64> index;
 | 
			
		||||
@ -295,7 +304,6 @@ union Instruction {
 | 
			
		||||
    BitField<20, 8, Register> gpr20;
 | 
			
		||||
    BitField<20, 7, SubOp> sub_op;
 | 
			
		||||
    BitField<28, 8, Register> gpr28;
 | 
			
		||||
    BitField<36, 13, u64> imm36;
 | 
			
		||||
    BitField<39, 8, Register> gpr39;
 | 
			
		||||
 | 
			
		||||
    union {
 | 
			
		||||
@ -316,6 +324,7 @@ union Instruction {
 | 
			
		||||
 | 
			
		||||
    Attribute attribute;
 | 
			
		||||
    Uniform uniform;
 | 
			
		||||
    Sampler sampler;
 | 
			
		||||
 | 
			
		||||
    u64 hex;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@ using Tegra::Shader::Attribute;
 | 
			
		||||
using Tegra::Shader::Instruction;
 | 
			
		||||
using Tegra::Shader::OpCode;
 | 
			
		||||
using Tegra::Shader::Register;
 | 
			
		||||
using Tegra::Shader::Sampler;
 | 
			
		||||
using Tegra::Shader::SubOp;
 | 
			
		||||
using Tegra::Shader::Uniform;
 | 
			
		||||
 | 
			
		||||
@ -186,13 +187,13 @@ private:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Generates code representing a temporary (GPR) register.
 | 
			
		||||
    std::string GetRegister(const Register& reg) {
 | 
			
		||||
        if (stage == Maxwell3D::Regs::ShaderStage::Fragment && reg.GetIndex() < 4) {
 | 
			
		||||
    std::string GetRegister(const Register& reg, unsigned elem = 0) {
 | 
			
		||||
        if (stage == Maxwell3D::Regs::ShaderStage::Fragment && reg < 4) {
 | 
			
		||||
            // GPRs 0-3 are output color for the fragment shader
 | 
			
		||||
            return std::string{"color."} + "rgba"[reg.GetIndex()];
 | 
			
		||||
            return std::string{"color."} + "rgba"[reg + elem];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return *declr_register.insert("register_" + std::to_string(reg)).first;
 | 
			
		||||
        return *declr_register.insert("register_" + std::to_string(reg + elem)).first;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Generates code representing a uniform (C buffer) register.
 | 
			
		||||
@ -201,6 +202,15 @@ private:
 | 
			
		||||
        return 'c' + std::to_string(reg.index) + '[' + std::to_string(reg.offset) + ']';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Generates code representing a texture sampler.
 | 
			
		||||
    std::string GetSampler(const Sampler& sampler) const {
 | 
			
		||||
        // TODO(Subv): Support more than just texture sampler 0
 | 
			
		||||
        ASSERT_MSG(sampler.index == Sampler::Index::Sampler_0, "unsupported");
 | 
			
		||||
        const unsigned index{static_cast<unsigned>(sampler.index.Value()) -
 | 
			
		||||
                             static_cast<unsigned>(Sampler::Index::Sampler_0)};
 | 
			
		||||
        return "tex[" + std::to_string(index) + "]";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds code that calls a subroutine.
 | 
			
		||||
     * @param subroutine the subroutine to call.
 | 
			
		||||
@ -245,7 +255,7 @@ private:
 | 
			
		||||
 | 
			
		||||
        switch (OpCode::GetInfo(instr.opcode).type) {
 | 
			
		||||
        case OpCode::Type::Arithmetic: {
 | 
			
		||||
            ASSERT(!instr.alu.abs_d);
 | 
			
		||||
            ASSERT_MSG(!instr.alu.abs_d, "unimplemented");
 | 
			
		||||
 | 
			
		||||
            std::string dest = GetRegister(instr.gpr0);
 | 
			
		||||
            std::string op_a = instr.alu.negate_a ? "-" : "";
 | 
			
		||||
@ -330,15 +340,27 @@ private:
 | 
			
		||||
 | 
			
		||||
            switch (instr.opcode.EffectiveOpCode()) {
 | 
			
		||||
            case OpCode::Id::LD_A: {
 | 
			
		||||
                ASSERT(instr.attribute.fmt20.size == 0);
 | 
			
		||||
                ASSERT_MSG(instr.attribute.fmt20.size == 0, "untested");
 | 
			
		||||
                SetDest(instr.attribute.fmt20.element, gpr0, GetInputAttribute(attribute), 1, 4);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case OpCode::Id::ST_A: {
 | 
			
		||||
                ASSERT(instr.attribute.fmt20.size == 0);
 | 
			
		||||
                ASSERT_MSG(instr.attribute.fmt20.size == 0, "untested");
 | 
			
		||||
                SetDest(instr.attribute.fmt20.element, GetOutputAttribute(attribute), gpr0, 4, 1);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case OpCode::Id::TEXS: {
 | 
			
		||||
                ASSERT_MSG(instr.attribute.fmt20.size == 4, "untested");
 | 
			
		||||
                const std::string op_a = GetRegister(instr.gpr8);
 | 
			
		||||
                const std::string op_b = GetRegister(instr.gpr20);
 | 
			
		||||
                const std::string sampler = GetSampler(instr.sampler);
 | 
			
		||||
                const std::string coord = "vec2(" + op_a + ", " + op_b + ")";
 | 
			
		||||
                const std::string texture = "texture(" + sampler + ", " + coord + ")";
 | 
			
		||||
                for (unsigned elem = 0; elem < instr.attribute.fmt20.size; ++elem) {
 | 
			
		||||
                    SetDest(elem, GetRegister(instr.gpr0, elem), texture, 1, 4);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default: {
 | 
			
		||||
                LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: 0x%02x (%s): 0x%08x",
 | 
			
		||||
                             static_cast<unsigned>(instr.opcode.EffectiveOpCode()),
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user