From 7a990284c9207791af7b4f320fece8357a726720 Mon Sep 17 00:00:00 2001 From: bo3b Date: Fri, 16 Jan 2015 00:35:42 -0800 Subject: [PATCH] Restore the truncateTextureLoadPos routine for _LD. Found out why there was a second one of those- it returns different swizzle truncations because the operands are different for _LD and LDMS. Put that routine back and beefed up both of those to handle all known variants, report errors if something new and unknown is seen, and match on all possible string variants. There were some extra bugs there that should all be gone now. Ran against FC4 and gave a clean result- no warnings for these operands anymore. --- HLSLDecompiler/DecompileHLSL.cpp | 47 +++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/HLSLDecompiler/DecompileHLSL.cpp b/HLSLDecompiler/DecompileHLSL.cpp index b895cda53..41c988368 100644 --- a/HLSLDecompiler/DecompileHLSL.cpp +++ b/HLSLDecompiler/DecompileHLSL.cpp @@ -1620,18 +1620,45 @@ class Decompiler { // Normal variant like r1.xyxx int pos = 5; - if (!strncmp(textype, "Texture1D", 9)) pos = 2; // float - else if (!strncmp(textype, "Texture2D", 9)) pos = 3; // float2 - else if (!strncmp(textype, "Texture1DArray", 14)) pos = 3; - else if (!strncmp(textype, "Texture2DArray", 14)) pos = 4; // float3 - else if (!strncmp(textype, "Texture3D", 9)) pos = 4; - else if (!strncmp(textype, "TextureCube", 11)) pos = 4; - // float4 TextureCubeArray pos = 5 + if (!strncmp(textype, "Texture1D<", strlen("Texture1D<"))) pos = 2; // float .x + else if (!strncmp(textype, "Texture2DMS<", strlen("Texture2DMS<"))) pos = 3; // float2 .xy + else if (!strncmp(textype, "Texture1DArray<", strlen("Texture1DArray<"))) pos = 3; + else if (!strncmp(textype, "Texture2D<", strlen("Texture2D<"))) pos = 3; + else if (!strncmp(textype, "Texture2DMSArray<", strlen("Texture2DMSArray<"))) pos = 3; + else if (!strncmp(textype, "Texture2DArray<", strlen("Texture2DArray<"))) pos = 4; // float3 .xyz + else if (!strncmp(textype, "Texture3D<", strlen("Texture3D<"))) pos = 4; + else if (!strncmp(textype, "TextureCube<", strlen("TextureCube<"))) pos = 4; + else if (!strncmp(textype, "TextureCubeArray<", strlen("TextureCubeArray<"))) pos = 5; // float4 .xyzw + else logDecompileError(" unknown texture type for truncation: " + string(textype)); cpos = strrchr(op, '.'); cpos[pos] = 0; } } + + // This routine was expecting only r0.xyz type input parameters, but we can also get float4(0,0,0,0) type + // inputs as constants to things like .Load(). If it's a constant of any form, leave it unchanged. + // The reason there is a second version of this .xyzw truncator, is because this version is for the _LD + // operands, and for that version it's one parameter larger. Texture2D is 3 components, not 2 for this one. + // The extra bracket for comparison is to avoid early mismatch like Texture1D instead of Texture1DArray. + void truncateTextureLoadPos(char *op, const char *textype) + { + if (!strncmp(op, "float", 5)) + return; + + int pos = 5; // Might need 'Buffer' for int + if (!strncmp(textype, "Texture1D<", strlen("Texture1D<"))) pos = 3; // int2 .xy + else if (!strncmp(textype, "Texture2DMS<", strlen("Texture2DMS<"))) pos = 3; + else if (!strncmp(textype, "Texture1DArray<", strlen("Texture1DArray<"))) pos = 4; // int3 .xyz + else if (!strncmp(textype, "Texture2D<", strlen("Texture2D<"))) pos = 4; + else if (!strncmp(textype, "Texture2DMSArray<", strlen("Texture2DMSArray<"))) pos = 4; + else if (!strncmp(textype, "Texture2DArray<", strlen("Texture2DArray<"))) pos = 5; // int4 .xyzw + else if (!strncmp(textype, "Texture3D<", strlen("Texture3D<"))) pos = 5; + else logDecompileError(" unknown texture type for truncation: " + string(textype)); + char *cpos = strrchr(op, '.'); + cpos[pos] = 0; + } + void remapTarget(char *target) { char *pos = strchr(target, ','); @@ -3905,7 +3932,7 @@ class Decompiler applySwizzle(op1, op3); int textureId; sscanf_s(op3, "t%d.", &textureId); - truncateTexturePos(op2, mTextureType[textureId].c_str()); + truncateTextureLoadPos(op2, mTextureType[textureId].c_str()); if (!instr->bAddressOffset) sprintf(buffer, " %s = %s.Load(%s)%s;\n", writeTarget(op1), mTextureNames[textureId].c_str(), ci(op2).c_str(), strrchr(op3, '.')); else { @@ -3926,9 +3953,9 @@ class Decompiler applySwizzle(".x", fixImm(op4, instr->asOperands[3]), true); int textureId; sscanf_s(op3, "t%d.", &textureId); - truncateTexturePos(op2, mTextureType[textureId].c_str()); + truncateTextureLoadPos(op2, mTextureType[textureId].c_str()); if (!instr->bAddressOffset) - sprintf(buffer, " %s = %s.Load(%s,%s)%s;\n", writeTarget(op1), mTextureNames[textureId].c_str(), ci(op2).c_str(), ci(op4).c_str(), strrchr(op3, '.')); + sprintf(buffer, " %s = %s.Load(%s, %s)%s;\n", writeTarget(op1), mTextureNames[textureId].c_str(), ci(op2).c_str(), ci(op4).c_str(), strrchr(op3, '.')); else{ int offsetU = 0, offsetV = 0, offsetW = 0; sscanf_s(statement, "ld_aoffimmi(%d,%d,%d", &offsetU, &offsetV, &offsetW);