HLSL: Recognize POSITION semantic et al in DX9 compatibility mode (#2255)

diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index a7ce53d..871788e 100644
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -1593,7 +1593,8 @@
            "  --hlsl-iomap                      perform IO mapping in HLSL register space\n"
            "  --hlsl-enable-16bit-types         allow 16-bit types in SPIR-V for HLSL\n"
            "  --hlsl-dx9-compatible             interprets sampler declarations as a\n"
-           "                                    texture/sampler combo like DirectX9 would.\n"
+           "                                    texture/sampler combo like DirectX9 would,\n"
+           "                                    and recognizes DirectX9-specific semantics\n"
            "  --invert-y | --iy                 invert position.Y output in vertex shader\n"
            "  --keep-uncalled | --ku            don't eliminate uncalled functions\n"
            "  --nan-clamp                       favor non-NaN operand in min, max, and clamp\n"
diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h
index 5b63ff7..38693aa 100644
--- a/glslang/Public/ShaderLang.h
+++ b/glslang/Public/ShaderLang.h
@@ -255,7 +255,7 @@
     EShMsgDebugInfo        = (1 << 10), // save debug information
     EShMsgHlslEnable16BitTypes  = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL
     EShMsgHlslLegalization  = (1 << 12), // enable HLSL Legalization messages
-    EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (right now only for samplers)
+    EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics)
     EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table
     LAST_ELEMENT_MARKER(EShMsgCount),
 };
diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp
index 58c8b23..18ee4c4 100755
--- a/hlsl/hlslParseHelper.cpp
+++ b/hlsl/hlslParseHelper.cpp
@@ -6129,6 +6129,32 @@
         return semanticNum;
     };
 
+    if (builtIn == EbvNone && hlslDX9Compatible()) {
+        if (language == EShLangVertex) {
+            if (qualifier.isParamOutput()) {
+                if (upperCase == "POSITION") {
+                    builtIn = EbvPosition;
+                }
+                if (upperCase == "PSIZE") {
+                    builtIn = EbvPointSize;
+                }
+            }
+        } else if (language == EShLangFragment) {
+            if (qualifier.isParamInput() && upperCase == "VPOS") {
+                builtIn = EbvFragCoord;
+            }
+            if (qualifier.isParamOutput()) {
+                if (upperCase.compare(0, 5, "COLOR") == 0) {
+                    qualifier.layoutLocation = getSemanticNumber(upperCase, 0, nullptr);
+                    nextOutLocation = std::max(nextOutLocation, qualifier.layoutLocation + 1u);
+                }
+                if (upperCase == "DEPTH") {
+                    builtIn = EbvFragDepth;
+                }
+            }
+        }
+    }
+
     switch(builtIn) {
     case EbvNone:
         // Get location numbers from fragment outputs, instead of