mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	Merge pull request #355 from Subv/shader_instr
ShaderGen: Fixed TEXS overriding its own texcoords and implemented fmul32i
This commit is contained in:
		
						commit
						f633b0c875
					
				| @ -90,6 +90,7 @@ union OpCode { | |||||||
|     enum class Id : u64 { |     enum class Id : u64 { | ||||||
|         TEXS = 0x6C, |         TEXS = 0x6C, | ||||||
|         IPA = 0xE0, |         IPA = 0xE0, | ||||||
|  |         FMUL32_IMM = 0x1E, | ||||||
|         FFMA_IMM = 0x65, |         FFMA_IMM = 0x65, | ||||||
|         FFMA_CR = 0x93, |         FFMA_CR = 0x93, | ||||||
|         FFMA_RC = 0xA3, |         FFMA_RC = 0xA3, | ||||||
| @ -142,6 +143,7 @@ union OpCode { | |||||||
| 
 | 
 | ||||||
|         switch (op2) { |         switch (op2) { | ||||||
|         case Id::IPA: |         case Id::IPA: | ||||||
|  |         case Id::FMUL32_IMM: | ||||||
|             return op2; |             return op2; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -235,6 +237,7 @@ union OpCode { | |||||||
|         info_table[Id::FMUL_R] = {Type::Arithmetic, "fmul_r"}; |         info_table[Id::FMUL_R] = {Type::Arithmetic, "fmul_r"}; | ||||||
|         info_table[Id::FMUL_C] = {Type::Arithmetic, "fmul_c"}; |         info_table[Id::FMUL_C] = {Type::Arithmetic, "fmul_c"}; | ||||||
|         info_table[Id::FMUL_IMM] = {Type::Arithmetic, "fmul_imm"}; |         info_table[Id::FMUL_IMM] = {Type::Arithmetic, "fmul_imm"}; | ||||||
|  |         info_table[Id::FMUL32_IMM] = {Type::Arithmetic, "fmul32_imm"}; | ||||||
|         info_table[Id::FSETP_C] = {Type::Arithmetic, "fsetp_c"}; |         info_table[Id::FSETP_C] = {Type::Arithmetic, "fsetp_c"}; | ||||||
|         info_table[Id::FSETP_R] = {Type::Arithmetic, "fsetp_r"}; |         info_table[Id::FSETP_R] = {Type::Arithmetic, "fsetp_r"}; | ||||||
|         info_table[Id::EXIT] = {Type::Trivial, "exit"}; |         info_table[Id::EXIT] = {Type::Trivial, "exit"}; | ||||||
| @ -309,7 +312,8 @@ union Instruction { | |||||||
|     BitField<39, 8, Register> gpr39; |     BitField<39, 8, Register> gpr39; | ||||||
| 
 | 
 | ||||||
|     union { |     union { | ||||||
|         BitField<20, 19, u64> imm20; |         BitField<20, 19, u64> imm20_19; | ||||||
|  |         BitField<20, 32, u64> imm20_32; | ||||||
|         BitField<45, 1, u64> negate_b; |         BitField<45, 1, u64> negate_b; | ||||||
|         BitField<46, 1, u64> abs_a; |         BitField<46, 1, u64> abs_a; | ||||||
|         BitField<48, 1, u64> negate_a; |         BitField<48, 1, u64> negate_a; | ||||||
| @ -317,14 +321,21 @@ union Instruction { | |||||||
|         BitField<50, 1, u64> abs_d; |         BitField<50, 1, u64> abs_d; | ||||||
|         BitField<56, 1, u64> negate_imm; |         BitField<56, 1, u64> negate_imm; | ||||||
| 
 | 
 | ||||||
|         float GetImm20() const { |         float GetImm20_19() const { | ||||||
|             float result{}; |             float result{}; | ||||||
|             u32 imm{static_cast<u32>(imm20)}; |             u32 imm{static_cast<u32>(imm20_19)}; | ||||||
|             imm <<= 12; |             imm <<= 12; | ||||||
|             imm |= negate_imm ? 0x80000000 : 0; |             imm |= negate_imm ? 0x80000000 : 0; | ||||||
|             std::memcpy(&result, &imm, sizeof(imm)); |             std::memcpy(&result, &imm, sizeof(imm)); | ||||||
|             return result; |             return result; | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         float GetImm20_32() const { | ||||||
|  |             float result{}; | ||||||
|  |             u32 imm{static_cast<u32>(imm20_32)}; | ||||||
|  |             std::memcpy(&result, &imm, sizeof(imm)); | ||||||
|  |             return result; | ||||||
|  |         } | ||||||
|     } alu; |     } alu; | ||||||
| 
 | 
 | ||||||
|     union { |     union { | ||||||
|  | |||||||
| @ -190,9 +190,14 @@ private: | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Generates code representing an immediate value
 |     /// Generates code representing a 19-bit immediate value
 | ||||||
|     static std::string GetImmediate(const Instruction& instr) { |     static std::string GetImmediate19(const Instruction& instr) { | ||||||
|         return std::to_string(instr.alu.GetImm20()); |         return std::to_string(instr.alu.GetImm20_19()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Generates code representing a 32-bit immediate value
 | ||||||
|  |     static std::string GetImmediate32(const Instruction& instr) { | ||||||
|  |         return std::to_string(instr.alu.GetImm20_32()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Generates code representing a temporary (GPR) register.
 |     /// Generates code representing a temporary (GPR) register.
 | ||||||
| @ -276,7 +281,7 @@ private: | |||||||
|             std::string op_b = instr.alu.negate_b ? "-" : ""; |             std::string op_b = instr.alu.negate_b ? "-" : ""; | ||||||
| 
 | 
 | ||||||
|             if (instr.is_b_imm) { |             if (instr.is_b_imm) { | ||||||
|                 op_b += GetImmediate(instr); |                 op_b += GetImmediate19(instr); | ||||||
|             } else { |             } else { | ||||||
|                 if (instr.is_b_gpr) { |                 if (instr.is_b_gpr) { | ||||||
|                     op_b += GetRegister(instr.gpr20); |                     op_b += GetRegister(instr.gpr20); | ||||||
| @ -296,6 +301,11 @@ private: | |||||||
|                 SetDest(0, dest, op_a + " * " + op_b, 1, 1, instr.alu.abs_d); |                 SetDest(0, dest, op_a + " * " + op_b, 1, 1, instr.alu.abs_d); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|  |             case OpCode::Id::FMUL32_IMM: { | ||||||
|  |                 // fmul32i doesn't have abs or neg bits.
 | ||||||
|  |                 SetDest(0, dest, GetRegister(instr.gpr8) + " * " + GetImmediate32(instr), 1, 1); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|             case OpCode::Id::FADD_C: |             case OpCode::Id::FADD_C: | ||||||
|             case OpCode::Id::FADD_R: |             case OpCode::Id::FADD_R: | ||||||
|             case OpCode::Id::FADD_IMM: { |             case OpCode::Id::FADD_IMM: { | ||||||
| @ -364,7 +374,7 @@ private: | |||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             case OpCode::Id::FFMA_IMM: { |             case OpCode::Id::FFMA_IMM: { | ||||||
|                 op_b += GetImmediate(instr); |                 op_b += GetImmediate19(instr); | ||||||
|                 op_c += GetRegister(instr.gpr39); |                 op_c += GetRegister(instr.gpr39); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
| @ -399,11 +409,18 @@ private: | |||||||
|                 const std::string op_a = GetRegister(instr.gpr8); |                 const std::string op_a = GetRegister(instr.gpr8); | ||||||
|                 const std::string op_b = GetRegister(instr.gpr20); |                 const std::string op_b = GetRegister(instr.gpr20); | ||||||
|                 const std::string sampler = GetSampler(instr.sampler); |                 const std::string sampler = GetSampler(instr.sampler); | ||||||
|                 const std::string coord = "vec2(" + op_a + ", " + op_b + ")"; |                 const std::string coord = "vec2 coords = vec2(" + op_a + ", " + op_b + ");"; | ||||||
|                 const std::string texture = "texture(" + sampler + ", " + coord + ")"; |                 // Add an extra scope and declare the texture coords inside to prevent overwriting
 | ||||||
|  |                 // them in case they are used as outputs of the texs instruction.
 | ||||||
|  |                 shader.AddLine("{"); | ||||||
|  |                 ++shader.scope; | ||||||
|  |                 shader.AddLine(coord); | ||||||
|  |                 const std::string texture = "texture(" + sampler + ", coords)"; | ||||||
|                 for (unsigned elem = 0; elem < instr.attribute.fmt20.size; ++elem) { |                 for (unsigned elem = 0; elem < instr.attribute.fmt20.size; ++elem) { | ||||||
|                     SetDest(elem, GetRegister(instr.gpr0, elem), texture, 1, 4); |                     SetDest(elem, GetRegister(instr.gpr0, elem), texture, 1, 4); | ||||||
|                 } |                 } | ||||||
|  |                 --shader.scope; | ||||||
|  |                 shader.AddLine("}"); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             default: { |             default: { | ||||||
| @ -586,7 +603,7 @@ private: | |||||||
|     std::set<Attribute::Index> declr_input_attribute; |     std::set<Attribute::Index> declr_input_attribute; | ||||||
|     std::set<Attribute::Index> declr_output_attribute; |     std::set<Attribute::Index> declr_output_attribute; | ||||||
|     std::array<ConstBufferEntry, Maxwell3D::Regs::MaxConstBuffers> declr_const_buffers; |     std::array<ConstBufferEntry, Maxwell3D::Regs::MaxConstBuffers> declr_const_buffers; | ||||||
| }; | }; // namespace Decompiler
 | ||||||
| 
 | 
 | ||||||
| std::string GetCommonDeclarations() { | std::string GetCommonDeclarations() { | ||||||
|     return "bool exec_shader();"; |     return "bool exec_shader();"; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 bunnei
						bunnei