From a00e51b5b254096616bdaa5c3029055e77f65e78 Mon Sep 17 00:00:00 2001
From: Rex Xu <rex.xu@amd.com>
Date: Mon, 12 Mar 2018 23:15:11 +0800
Subject: [PATCH] HLSL: Correct some mistakes for min16 types

- Add missing constructor ops to support float16/int16/uint16 types
- Allow half float literals
- Correct two errors of double literal parse in HLSL: extension check and
  postfix
---
 .../preprocessor/PpScanner.cpp                | 24 +++++++++------
 hlsl/hlslGrammar.cpp                          |  3 ++
 hlsl/hlslParseHelper.cpp                      | 30 +++++++++++++++++++
 hlsl/hlslScanContext.cpp                      |  1 +
 hlsl/hlslTokens.h                             |  1 +
 5 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/glslang/MachineIndependent/preprocessor/PpScanner.cpp
index 13e9c1d82..61bf027fa 100644
--- a/glslang/MachineIndependent/preprocessor/PpScanner.cpp
+++ b/glslang/MachineIndependent/preprocessor/PpScanner.cpp
@@ -174,16 +174,22 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
     // Suffix:
     bool isFloat16 = false;
     if (ch == 'l' || ch == 'L') {
-        parseContext.doubleCheck(ppToken->loc, "double floating-point suffix");
+        if (parseContext.intermediate.getSource() == EShSourceGlsl)
+            parseContext.doubleCheck(ppToken->loc, "double floating-point suffix");
         if (! HasDecimalOrExponent)
             parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
-        int ch2 = getChar();
-        if (ch2 != 'f' && ch2 != 'F') {
-            ungetChar();
-            ungetChar();
-        } else {
+        if (parseContext.intermediate.getSource() == EShSourceGlsl) {
+            int ch2 = getChar();
+            if (ch2 != 'f' && ch2 != 'F') {
+                ungetChar();
+                ungetChar();
+            } else {
+                saveName(ch);
+                saveName(ch2);
+                isDouble = 1;
+            }
+        } else if (parseContext.intermediate.getSource() == EShSourceHlsl) {
             saveName(ch);
-            saveName(ch2);
             isDouble = 1;
         }
     } else if (ch == 'h' || ch == 'H') {
@@ -201,9 +207,9 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
                 saveName(ch2);
                 isFloat16 = true;
             }
-        } else {
+        } else if (parseContext.intermediate.getSource() == EShSourceHlsl) {
             saveName(ch);
-            isFloat16 = false;
+            isFloat16 = true;
         }
     } else if (ch == 'f' || ch == 'F') {
         parseContext.profileRequires(ppToken->loc,  EEsProfile, 300, nullptr, "floating-point suffix");
diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp
index 38a611662..24ba48981 100755
--- a/hlsl/hlslGrammar.cpp
+++ b/hlsl/hlslGrammar.cpp
@@ -3283,6 +3283,9 @@ bool HlslGrammar::acceptLiteral(TIntermTyped*& node)
     case EHTokUintConstant:
         node = intermediate.addConstantUnion(token.u, token.loc, true);
         break;
+    case EHTokFloat16Constant:
+        node = intermediate.addConstantUnion(token.d, EbtFloat16, token.loc, true);
+        break;
     case EHTokFloatConstant:
         node = intermediate.addConstantUnion(token.d, EbtFloat, token.loc, true);
         break;
diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp
index 73bda6d64..fbfc428ef 100755
--- a/hlsl/hlslParseHelper.cpp
+++ b/hlsl/hlslParseHelper.cpp
@@ -8320,6 +8320,22 @@ TIntermTyped* HlslParseContext::constructBuiltIn(const TType& type, TOperator op
     // First, convert types as needed.
     //
     switch (op) {
+    case EOpConstructF16Vec2:
+    case EOpConstructF16Vec3:
+    case EOpConstructF16Vec4:
+    case EOpConstructF16Mat2x2:
+    case EOpConstructF16Mat2x3:
+    case EOpConstructF16Mat2x4:
+    case EOpConstructF16Mat3x2:
+    case EOpConstructF16Mat3x3:
+    case EOpConstructF16Mat3x4:
+    case EOpConstructF16Mat4x2:
+    case EOpConstructF16Mat4x3:
+    case EOpConstructF16Mat4x4:
+    case EOpConstructFloat16:
+        basicOp = EOpConstructFloat16;
+        break;
+
     case EOpConstructVec2:
     case EOpConstructVec3:
     case EOpConstructVec4:
@@ -8352,6 +8368,13 @@ TIntermTyped* HlslParseContext::constructBuiltIn(const TType& type, TOperator op
         basicOp = EOpConstructDouble;
         break;
 
+    case EOpConstructI16Vec2:
+    case EOpConstructI16Vec3:
+    case EOpConstructI16Vec4:
+    case EOpConstructInt16:
+        basicOp = EOpConstructInt16;
+        break;
+
     case EOpConstructIVec2:
     case EOpConstructIVec3:
     case EOpConstructIVec4:
@@ -8368,6 +8391,13 @@ TIntermTyped* HlslParseContext::constructBuiltIn(const TType& type, TOperator op
         basicOp = EOpConstructInt;
         break;
 
+    case EOpConstructU16Vec2:
+    case EOpConstructU16Vec3:
+    case EOpConstructU16Vec4:
+    case EOpConstructUint16:
+        basicOp = EOpConstructUint16;
+        break;
+
     case EOpConstructUVec2:
     case EOpConstructUVec3:
     case EOpConstructUVec4:
diff --git a/hlsl/hlslScanContext.cpp b/hlsl/hlslScanContext.cpp
index 06f767564..28a66bb47 100755
--- a/hlsl/hlslScanContext.cpp
+++ b/hlsl/hlslScanContext.cpp
@@ -550,6 +550,7 @@ EHlslTokenClass HlslScanContext::tokenizeClass(HlslToken& token)
 
         case PpAtomConstInt:           parserToken->i = ppToken.ival;       return EHTokIntConstant;
         case PpAtomConstUint:          parserToken->i = ppToken.ival;       return EHTokUintConstant;
+        case PpAtomConstFloat16:       parserToken->d = ppToken.dval;       return EHTokFloat16Constant;
         case PpAtomConstFloat:         parserToken->d = ppToken.dval;       return EHTokFloatConstant;
         case PpAtomConstDouble:        parserToken->d = ppToken.dval;       return EHTokDoubleConstant;
         case PpAtomIdentifier:
diff --git a/hlsl/hlslTokens.h b/hlsl/hlslTokens.h
index 9354ad925..4426bccec 100755
--- a/hlsl/hlslTokens.h
+++ b/hlsl/hlslTokens.h
@@ -298,6 +298,7 @@ enum EHlslTokenClass {
     EHTokConstantBuffer,
 
     // constant
+    EHTokFloat16Constant,
     EHTokFloatConstant,
     EHTokDoubleConstant,
     EHTokIntConstant,
-- 
GitLab