Vulkan:Include precision qualifier in GLSL

With this initial implementation, it's possible to get precision
qualifier mis-matches in the generated GLSL 4.50. According to the
spec this is allowed. From GLSLangSpec 4.50 section 4.7 "Precision and
Precision Qualifiers":

For the purposes of determining if an output from one shader stage
matches an input of the next stage, the precision qualifier need not
match.

However, when converted to SPIR-V and run through the shader validation
any mismatches will cause shader validation errors. Initially just
ignoring those errors with this commit.

Bug: angleproject:3078
Change-Id: Ia2b04f90f0a7b6b1302c1b1b3e32bcfd8db9ed49
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2057749
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Tobin Ehlis <tobine@google.com>
Reviewed-by: Tim Van Patten <timvp@google.com>
Commit-Queue: Tobin Ehlis <tobine@google.com>
diff --git a/src/compiler/translator/OutputVulkanGLSL.cpp b/src/compiler/translator/OutputVulkanGLSL.cpp
index 279f812..9d2105e 100644
--- a/src/compiler/translator/OutputVulkanGLSL.cpp
+++ b/src/compiler/translator/OutputVulkanGLSL.cpp
@@ -27,6 +27,7 @@
                                      sh::GLenum shaderType,
                                      int shaderVersion,
                                      ShShaderOutput output,
+                                     bool forceHighp,
                                      ShCompileOptions compileOptions)
     : TOutputGLSL(objSink,
                   clampingStrategy,
@@ -39,7 +40,8 @@
                   compileOptions),
       mNextUnusedBinding(0),
       mNextUnusedInputLocation(0),
-      mNextUnusedOutputLocation(0)
+      mNextUnusedOutputLocation(0),
+      mForceHighp(forceHighp)
 {}
 
 void TOutputVulkanGLSL::writeLayoutQualifier(TIntermTyped *variable)
@@ -168,4 +170,17 @@
     }
 }
 
+bool TOutputVulkanGLSL::writeVariablePrecision(TPrecision precision)
+{
+    if (precision == EbpUndefined)
+        return false;
+
+    TInfoSinkBase &out = objSink();
+    if (mForceHighp)
+        out << getPrecisionString(EbpHigh);
+    else
+        out << getPrecisionString(precision);
+    return true;
+}
+
 }  // namespace sh
diff --git a/src/compiler/translator/OutputVulkanGLSL.h b/src/compiler/translator/OutputVulkanGLSL.h
index 6ad6154..18eaa6e 100644
--- a/src/compiler/translator/OutputVulkanGLSL.h
+++ b/src/compiler/translator/OutputVulkanGLSL.h
@@ -25,6 +25,7 @@
                       sh::GLenum shaderType,
                       int shaderVersion,
                       ShShaderOutput output,
+                      bool forceHighp,
                       ShCompileOptions compileOptions);
 
     void writeStructType(const TStructure *structure);
@@ -48,6 +49,7 @@
     void writeVariableType(const TType &type,
                            const TSymbol *symbol,
                            bool isFunctionArgument) override;
+    bool writeVariablePrecision(TPrecision) override;
 
     // Every resource that requires set & binding layout qualifiers is assigned set 0 and an
     // arbitrary binding when outputting GLSL.  Every input/output that requires a location
@@ -57,6 +59,9 @@
     uint32_t mNextUnusedBinding;
     uint32_t mNextUnusedInputLocation;
     uint32_t mNextUnusedOutputLocation;
+
+  private:
+    bool mForceHighp;
 };
 
 }  // namespace sh
diff --git a/src/compiler/translator/OutputVulkanGLSLForMetal.mm b/src/compiler/translator/OutputVulkanGLSLForMetal.mm
index 35e06eb..a3c143a 100644
--- a/src/compiler/translator/OutputVulkanGLSLForMetal.mm
+++ b/src/compiler/translator/OutputVulkanGLSLForMetal.mm
@@ -71,6 +71,7 @@
                         shaderType,
                         shaderVersion,
                         output,
+                        false,
                         compileOptions)
 {}
 
diff --git a/src/compiler/translator/TranslatorMetal.cpp b/src/compiler/translator/TranslatorMetal.cpp
index ce4e9ea..2936b1e 100644
--- a/src/compiler/translator/TranslatorMetal.cpp
+++ b/src/compiler/translator/TranslatorMetal.cpp
@@ -67,9 +67,10 @@
                                 PerformanceDiagnostics *perfDiagnostics)
 {
     TInfoSinkBase &sink = getInfoSink().obj;
+
     TOutputVulkanGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(),
                                  getNameMap(), &getSymbolTable(), getShaderType(),
-                                 getShaderVersion(), getOutputType(), compileOptions);
+                                 getShaderVersion(), getOutputType(), false, compileOptions);
 
     const TVariable *driverUniforms = nullptr;
     if (!TranslatorVulkan::translateImpl(root, compileOptions, perfDiagnostics, &driverUniforms,
diff --git a/src/compiler/translator/TranslatorVulkan.cpp b/src/compiler/translator/TranslatorVulkan.cpp
index d65736f..717a65e 100644
--- a/src/compiler/translator/TranslatorVulkan.cpp
+++ b/src/compiler/translator/TranslatorVulkan.cpp
@@ -1008,9 +1008,14 @@
 {
 
     TInfoSinkBase &sink = getInfoSink().obj;
-    TOutputVulkanGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(),
-                                 getNameMap(), &getSymbolTable(), getShaderType(),
-                                 getShaderVersion(), getOutputType(), compileOptions);
+
+    bool precisionEmulation = false;
+    if (!emulatePrecisionIfNeeded(root, sink, &precisionEmulation, SH_GLSL_VULKAN_OUTPUT))
+        return false;
+
+    TOutputVulkanGLSL outputGLSL(
+        sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), &getSymbolTable(),
+        getShaderType(), getShaderVersion(), getOutputType(), precisionEmulation, compileOptions);
 
     if (!translateImpl(root, compileOptions, perfDiagnostics, nullptr, &outputGLSL))
     {
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.cpp b/src/libANGLE/renderer/vulkan/RendererVk.cpp
index ee39d64..211f9be 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RendererVk.cpp
@@ -124,9 +124,9 @@
     "VUID-vkDestroySemaphore-semaphore-parameter",
     // http://anglebug.com/4063
     "VUID-VkDeviceCreateInfo-pNext-pNext",
-    "VUID-VkPipelineRasterizationStateCreateInfo-pNext-pNext",
-    "VUID_Undefined",
-};
+    "VUID-VkPipelineRasterizationStateCreateInfo-pNext-pNext", "VUID_Undefined",
+    // http://anglebug.com/3078
+    "UNASSIGNED-CoreValidation-Shader-InterfaceTypeMismatch"};
 
 // Suppress validation errors that are known
 //  return "true" if given code/prefix/message is known, else return "false"
diff --git a/src/tests/deqp_support/deqp_gles3_test_expectations.txt b/src/tests/deqp_support/deqp_gles3_test_expectations.txt
index 178d770..35209d1 100644
--- a/src/tests/deqp_support/deqp_gles3_test_expectations.txt
+++ b/src/tests/deqp_support/deqp_gles3_test_expectations.txt
@@ -567,6 +567,14 @@
 2830 ANDROID VULKAN : dEQP-GLES3.functional.rasterization.fbo.texture_2d.primitives.lines = FAIL
 2830 ANDROID VULKAN : dEQP-GLES3.functional.rasterization.primitives.line* = FAIL
 2808 ANDROID VULKAN : dEQP-GLES3.functional.shaders.builtin_variable.fragcoord_w = FAIL
+3078 ANDROID VULKAN : dEQP-GLES3.functional.shaders.operator.unary_operator.minus.lowp_uint_fragment = FAIL
+3078 ANDROID VULKAN : dEQP-GLES3.functional.shaders.operator.unary_operator.minus.lowp_uvec2_fragment = FAIL
+3078 ANDROID VULKAN : dEQP-GLES3.functional.shaders.operator.unary_operator.minus.lowp_uvec3_fragment = FAIL
+3078 ANDROID VULKAN : dEQP-GLES3.functional.shaders.operator.unary_operator.minus.lowp_uvec4_fragment = FAIL
+3078 ANDROID VULKAN : dEQP-GLES3.functional.shaders.operator.unary_operator.minus.mediump_uint_fragment = FAIL
+3078 ANDROID VULKAN : dEQP-GLES3.functional.shaders.operator.unary_operator.minus.mediump_uvec2_fragment = FAIL
+3078 ANDROID VULKAN : dEQP-GLES3.functional.shaders.operator.unary_operator.minus.mediump_uvec3_fragment = FAIL
+3078 ANDROID VULKAN : dEQP-GLES3.functional.shaders.operator.unary_operator.minus.mediump_uvec4_fragment = FAIL
 
 // Pixel driver issues
 4024 PIXEL2ORXL VULKAN : dEQP-GLES3.functional.draw.random.5 = SKIP