From 3aaa2645fa9f9e5123641628f545070d036748d4 Mon Sep 17 00:00:00 2001 From: Andres Traks Date: Sun, 26 Jan 2025 15:33:19 +0200 Subject: [PATCH] Fix depth write mask --- DirectXShaderModel/AsmWriter.cs | 4 ++-- DirectXShaderModel/D3D10Instruction.cs | 11 ++++++++++- DirectXShaderModel/D3D9Instruction.cs | 10 ++++++++++ DirectXShaderModel/Instruction.cs | 16 ++++++---------- Hlsl/HlslSimpleWriter.cs | 12 ++++++++++-- .../ps_3_0_instruction/semantics.fx | 2 +- 6 files changed, 39 insertions(+), 16 deletions(-) diff --git a/DirectXShaderModel/AsmWriter.cs b/DirectXShaderModel/AsmWriter.cs index 13c4f88..139a199 100644 --- a/DirectXShaderModel/AsmWriter.cs +++ b/DirectXShaderModel/AsmWriter.cs @@ -30,8 +30,8 @@ static string GetDestinationName(Instruction instruction) { int destIndex = instruction.GetDestinationParamIndex(); string registerName = instruction.GetParamRegisterName(destIndex); - const int registerLength = 4; - string writeMaskName = instruction.GetDestinationWriteMaskName(registerLength, false); + int destinationLength = instruction.GetDestinationSemanticSize(); + string writeMaskName = instruction.GetDestinationWriteMaskName(destinationLength); return $"{registerName}{writeMaskName}"; } diff --git a/DirectXShaderModel/D3D10Instruction.cs b/DirectXShaderModel/D3D10Instruction.cs index fc611c1..7019f0f 100644 --- a/DirectXShaderModel/D3D10Instruction.cs +++ b/DirectXShaderModel/D3D10Instruction.cs @@ -275,7 +275,7 @@ public override string GetSourceSwizzleName(int srcIndex, int? destinationLength public override string GetDeclSemantic() { string name; - switch (GetOperandType(0)) + switch (GetOperandType(GetDestinationParamIndex())) { case OperandType.Input: name = "SV_Position"; @@ -294,6 +294,15 @@ public override string GetDeclSemantic() return name; } + public override int GetDestinationSemanticSize() + { + if (GetOperandType(GetDestinationParamIndex()) == OperandType.OutputDepth) + { + return 1; + } + return 4; + } + private byte[] GetOperandValueBytes(int index, int componentIndex) { Span span = OperandTokens.GetSpan(index); diff --git a/DirectXShaderModel/D3D9Instruction.cs b/DirectXShaderModel/D3D9Instruction.cs index 1151d51..eb902e3 100644 --- a/DirectXShaderModel/D3D9Instruction.cs +++ b/DirectXShaderModel/D3D9Instruction.cs @@ -146,6 +146,16 @@ public SamplerTextureType GetDeclSamplerTextureType() return (SamplerTextureType)((Params[0] >> 27) & 0xF); } + public override int GetDestinationSemanticSize() + { + RegisterType registerType = GetParamRegisterType(GetDestinationParamIndex()); + if (registerType == RegisterType.DepthOut) + { + return 1; + } + return 4; + } + public override int GetDestinationParamIndex() { if (Opcode == Opcode.Dcl) return 1; diff --git a/DirectXShaderModel/Instruction.cs b/DirectXShaderModel/Instruction.cs index f359cfc..a395863 100644 --- a/DirectXShaderModel/Instruction.cs +++ b/DirectXShaderModel/Instruction.cs @@ -21,18 +21,12 @@ public abstract class Instruction public abstract int GetDestinationWriteMask(); - public string GetDestinationWriteMaskName(int destinationLength, bool hlsl) + public string GetDestinationWriteMaskName(int destinationLength) { - int writeMask = GetDestinationWriteMask(); - int writeMaskLength = GetDestinationMaskLength(); + int destinationMask = (1 << destinationLength) - 1; + int writeMask = GetDestinationWriteMask() & destinationMask; - if (!hlsl) - { - destinationLength = 4; // explicit mask in assembly - } - - // Check if mask is the same length and of the form .xyzw - if (writeMaskLength == destinationLength && writeMask == ((1 << writeMaskLength) - 1)) + if (writeMask == destinationMask) { return ""; } @@ -77,5 +71,7 @@ public byte[] GetSourceSwizzleComponents(int srcIndex) public abstract string GetSourceSwizzleName(int srcIndex, int? destinationLength); public abstract string GetDeclSemantic(); + + public abstract int GetDestinationSemanticSize(); } } diff --git a/Hlsl/HlslSimpleWriter.cs b/Hlsl/HlslSimpleWriter.cs index 2ddb685..78dd830 100644 --- a/Hlsl/HlslSimpleWriter.cs +++ b/Hlsl/HlslSimpleWriter.cs @@ -353,7 +353,7 @@ private string GetDestinationName(Instruction instruction) string registerName = _registers.GetRegisterName(registerKey); registerName = registerName ?? instruction.GetParamRegisterName(destIndex); int registerLength = _registers.GetRegisterFullLength(registerKey); - string writeMaskName = instruction.GetDestinationWriteMaskName(registerLength, true); + string writeMaskName = instruction.GetDestinationWriteMaskName(registerLength); return string.Format("{0}{1}", registerName, writeMaskName); } @@ -452,7 +452,15 @@ private string GetSourceConstantValue(D3D9Instruction instruction, int srcIndex, { if (instruction.HasDestination) { - destinationLength = instruction.GetDestinationMaskLength(); + int writeMask = instruction.GetDestinationWriteMask(); + destinationLength = 0; + for (int i = 0; i < 4; i++) + { + if ((writeMask & (1 << i)) != 0) + { + destinationLength++; + } + } } else { diff --git a/HlslDecompiler.Tests/ShaderSources/ps_3_0_instruction/semantics.fx b/HlslDecompiler.Tests/ShaderSources/ps_3_0_instruction/semantics.fx index 17e70e1..c3443f4 100644 --- a/HlslDecompiler.Tests/ShaderSources/ps_3_0_instruction/semantics.fx +++ b/HlslDecompiler.Tests/ShaderSources/ps_3_0_instruction/semantics.fx @@ -16,7 +16,7 @@ PS_OUT main(PS_IN i) o.color.w = (i.vface >= 0) ? 1 : -1; o.color.xyz = i.vpos.xxy * float3(0, 1, 1) + float3(0.3, 0, 0); - o.depth.xyzw = -123456; + o.depth = -123456; return o; }