mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-10-30 07:29:02 -05:00 
			
		
		
		
	gl_shader_decompiler: Implement TEXS.F16
This commit is contained in:
		| @@ -1049,6 +1049,7 @@ union Instruction { | ||||
|         BitField<49, 1, u64> nodep_flag; | ||||
|         BitField<50, 3, u64> component_mask_selector; | ||||
|         BitField<53, 4, u64> texture_info; | ||||
|         BitField<60, 1, u64> fp32_flag; | ||||
|  | ||||
|         TextureType GetTextureType() const { | ||||
|             // The TEXS instruction has a weird encoding for the texture type. | ||||
| @@ -1549,7 +1550,7 @@ private: | ||||
|             INST("1110111011011---", Id::STG, Type::Memory, "STG"), | ||||
|             INST("110000----111---", Id::TEX, Type::Memory, "TEX"), | ||||
|             INST("1101111101001---", Id::TXQ, Type::Memory, "TXQ"), | ||||
|             INST("1101100---------", Id::TEXS, Type::Memory, "TEXS"), | ||||
|             INST("1101-00---------", Id::TEXS, Type::Memory, "TEXS"), | ||||
|             INST("1101101---------", Id::TLDS, Type::Memory, "TLDS"), | ||||
|             INST("110010----111---", Id::TLD4, Type::Memory, "TLD4"), | ||||
|             INST("1101111100------", Id::TLD4S, Type::Memory, "TLD4S"), | ||||
|   | ||||
| @@ -50,6 +50,14 @@ public: | ||||
|     using std::runtime_error::runtime_error; | ||||
| }; | ||||
|  | ||||
| /// Generates code to use for a swizzle operation. | ||||
| static std::string GetSwizzle(u64 elem) { | ||||
|     ASSERT(elem <= 3); | ||||
|     std::string swizzle = "."; | ||||
|     swizzle += "xyzw"[elem]; | ||||
|     return swizzle; | ||||
| } | ||||
|  | ||||
| /// Translate topology | ||||
| static std::string GetTopologyName(Tegra::Shader::OutputTopology topology) { | ||||
|     switch (topology) { | ||||
| @@ -1004,14 +1012,6 @@ private: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Generates code to use for a swizzle operation. | ||||
|     static std::string GetSwizzle(u64 elem) { | ||||
|         ASSERT(elem <= 3); | ||||
|         std::string swizzle = "."; | ||||
|         swizzle += "xyzw"[elem]; | ||||
|         return swizzle; | ||||
|     } | ||||
|  | ||||
|     ShaderWriter& shader; | ||||
|     ShaderWriter& declarations; | ||||
|     std::vector<GLSLRegister> regs; | ||||
| @@ -1343,7 +1343,7 @@ private: | ||||
|         regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); | ||||
|     } | ||||
|  | ||||
|     void WriteTexsInstruction(const Instruction& instr, const std::string& texture) { | ||||
|     void WriteTexsInstructionFloat(const Instruction& instr, const std::string& texture) { | ||||
|         // TEXS has two destination registers and a swizzle. The first two elements in the swizzle | ||||
|         // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 | ||||
|  | ||||
| @@ -1368,6 +1368,38 @@ private: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void WriteTexsInstructionHalfFloat(const Instruction& instr, const std::string& texture) { | ||||
|         // TEXS.F16 destionation registers are packed in two registers in pairs (just like any half | ||||
|         // float instruction). | ||||
|  | ||||
|         std::array<std::string, 4> components; | ||||
|         u32 written_components = 0; | ||||
|  | ||||
|         for (u32 component = 0; component < 4; ++component) { | ||||
|             if (!instr.texs.IsComponentEnabled(component)) | ||||
|                 continue; | ||||
|             components[written_components++] = texture + GetSwizzle(component); | ||||
|         } | ||||
|         if (written_components == 0) | ||||
|             return; | ||||
|  | ||||
|         const auto BuildComponent = [&](std::string low, std::string high, bool high_enabled) { | ||||
|             return "vec2(" + low + ", " + (high_enabled ? high : "0") + ')'; | ||||
|         }; | ||||
|  | ||||
|         regs.SetRegisterToHalfFloat( | ||||
|             instr.gpr0, 0, BuildComponent(components[0], components[1], written_components > 1), | ||||
|             Tegra::Shader::HalfMerge::H0_H1, 1, 1); | ||||
|  | ||||
|         if (written_components > 2) { | ||||
|             ASSERT(instr.texs.HasTwoDestinations()); | ||||
|             regs.SetRegisterToHalfFloat( | ||||
|                 instr.gpr28, 0, | ||||
|                 BuildComponent(components[2], components[3], written_components > 3), | ||||
|                 Tegra::Shader::HalfMerge::H0_H1, 1, 1); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) { | ||||
|         switch (texture_type) { | ||||
|         case Tegra::Shader::TextureType::Texture1D: | ||||
| @@ -2782,7 +2814,11 @@ private: | ||||
|                 } | ||||
|                 shader.AddLine("vec4 texture_tmp = " + texture + ';'); | ||||
|  | ||||
|                 WriteTexsInstruction(instr, "texture_tmp"); | ||||
|                 if (instr.texs.fp32_flag) { | ||||
|                     WriteTexsInstructionFloat(instr, "texture_tmp"); | ||||
|                 } else { | ||||
|                     WriteTexsInstructionHalfFloat(instr, "texture_tmp"); | ||||
|                 } | ||||
|                 break; | ||||
|             } | ||||
|             case OpCode::Id::TLDS: { | ||||
| @@ -2841,7 +2877,7 @@ private: | ||||
|                     } | ||||
|                 }(); | ||||
|  | ||||
|                 WriteTexsInstruction(instr, texture); | ||||
|                 WriteTexsInstructionFloat(instr, texture); | ||||
|                 break; | ||||
|             } | ||||
|             case OpCode::Id::TLD4: { | ||||
| @@ -2939,7 +2975,8 @@ private: | ||||
|                 if (depth_compare) { | ||||
|                     texture = "vec4(" + texture + ')'; | ||||
|                 } | ||||
|                 WriteTexsInstruction(instr, texture); | ||||
|  | ||||
|                 WriteTexsInstructionFloat(instr, texture); | ||||
|                 break; | ||||
|             } | ||||
|             case OpCode::Id::TXQ: { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 ReinUsesLisp
					ReinUsesLisp