Fix Lod0 texture functions that take a bias parameter.

Texture functions that are in a divergent path can still take a bias parameter.
Treat the bias parameter as an explicit lod. The logic behind this is that the
implicit lod is considerd to be 0 like with other Lod0 functions, and then the
bias is added to it.

BUG=angle:604

Change-Id: I2dbc309c497d37e960209f08849f9d2bc9e1fbcc
Reviewed-on: https://chromium-review.googlesource.com/194544
Tested-by: Nicolas Capens <nicolascapens@chromium.org>
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 5520367..b05e6b6 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -56,9 +56,10 @@
     switch(method)
     {
       case IMPLICIT:                  break;
-      case BIAS:                      break;
+      case BIAS:                      break;   // Extra parameter makes the signature unique
       case LOD:      name += "Lod";   break;
       case LOD0:     name += "Lod0";  break;
+      case LOD0BIAS: name += "Lod0";  break;   // Extra parameter makes the signature unique
       case SIZE:     name += "Size";  break;
       case FETCH:    name += "Fetch"; break;
       case GRAD:     name += "Grad";  break;
@@ -982,6 +983,7 @@
               case TextureFunction::BIAS:     hlslCoords = 4; break;
               case TextureFunction::LOD:      hlslCoords = 4; break;
               case TextureFunction::LOD0:     hlslCoords = 4; break;
+              case TextureFunction::LOD0BIAS: hlslCoords = 4; break;
               default: UNREACHABLE();
             }
         }
@@ -1060,9 +1062,10 @@
         switch(textureFunction->method)
         {
           case TextureFunction::IMPLICIT:                        break;
-          case TextureFunction::BIAS:                            break;
+          case TextureFunction::BIAS:                            break;   // Comes after the offset parameter
           case TextureFunction::LOD:      out << ", float lod";  break;
           case TextureFunction::LOD0:                            break;
+          case TextureFunction::LOD0BIAS:                        break;   // Comes after the offset parameter
           case TextureFunction::SIZE:                            break;
           case TextureFunction::FETCH:    out << ", int mip";    break;
           case TextureFunction::GRAD:                            break;
@@ -1088,7 +1091,8 @@
             }
         }
 
-        if (textureFunction->method == TextureFunction::BIAS)
+        if (textureFunction->method == TextureFunction::BIAS ||
+            textureFunction->method == TextureFunction::LOD0BIAS)
         {
             out << ", float bias";
         }
@@ -1176,11 +1180,15 @@
                     if (IsSamplerArray(textureFunction->sampler))
                     {
                         out << "    float width; float height; float layers; float levels;\n";
-                            
+
                         if (textureFunction->method == TextureFunction::LOD0)
                         {
                             out << "    uint mip = 0;\n";
                         }
+                        else if (textureFunction->method == TextureFunction::LOD0BIAS)
+                        {
+                            out << "    uint mip = bias;\n";
+                        }
                         else
                         {
                             if (textureFunction->method == TextureFunction::IMPLICIT ||
@@ -1211,11 +1219,15 @@
                     else
                     {
                         out << "    float width; float height; float levels;\n";
-                             
+
                         if (textureFunction->method == TextureFunction::LOD0)
                         {
                             out << "    uint mip = 0;\n";
                         }
+                        else if (textureFunction->method == TextureFunction::LOD0BIAS)
+                        {
+                            out << "    uint mip = bias;\n";
+                        }
                         else
                         {
                             if (textureFunction->method == TextureFunction::IMPLICIT ||
@@ -1251,11 +1263,15 @@
                 else if (IsSampler3D(textureFunction->sampler))
                 {
                     out << "    float width; float height; float depth; float levels;\n";
-                      
+
                     if (textureFunction->method == TextureFunction::LOD0)
                     {
                         out << "    uint mip = 0;\n";
                     }
+                    else if (textureFunction->method == TextureFunction::LOD0BIAS)
+                    {
+                        out << "    uint mip = bias;\n";
+                    }
                     else
                     {
                         if (textureFunction->method == TextureFunction::IMPLICIT ||
@@ -1304,6 +1320,7 @@
                   case TextureFunction::BIAS:     out << "bias(s, "; break;
                   case TextureFunction::LOD:      out << "lod(s, ";  break;
                   case TextureFunction::LOD0:     out << "lod(s, ";  break;
+                  case TextureFunction::LOD0BIAS: out << "lod(s, ";  break;
                   default: UNREACHABLE();
                 }
             }
@@ -1341,6 +1358,7 @@
                       case TextureFunction::BIAS:     out << "x.SampleBias(s, ";  break;
                       case TextureFunction::LOD:      out << "x.SampleLevel(s, "; break;
                       case TextureFunction::LOD0:     out << "x.SampleLevel(s, "; break;
+                      case TextureFunction::LOD0BIAS: out << "x.SampleLevel(s, "; break;
                       default: UNREACHABLE();
                     }
                 }
@@ -1428,9 +1446,10 @@
                 {
                     switch(textureFunction->method)
                     {
-                      case TextureFunction::BIAS: out << ", bias"; break;
-                      case TextureFunction::LOD:  out << ", lod";  break;
-                      case TextureFunction::LOD0: out << ", 0";    break;
+                      case TextureFunction::BIAS:     out << ", bias"; break;
+                      case TextureFunction::LOD:      out << ", lod";  break;
+                      case TextureFunction::LOD0:     out << ", 0";    break;
+                      case TextureFunction::LOD0BIAS: out << ", bias"; break;
                       default: UNREACHABLE();
                     }
                 }
@@ -1495,6 +1514,7 @@
                       case TextureFunction::BIAS:     out << "), bias"; break;
                       case TextureFunction::LOD:      out << "), lod";  break;
                       case TextureFunction::LOD0:     out << "), 0";    break;
+                      case TextureFunction::LOD0BIAS: out << "), bias"; break;
                       default: UNREACHABLE();
                     }
                 }
@@ -2537,31 +2557,37 @@
 
                 if (textureFunction.method == TextureFunction::IMPLICIT)   // Could require lod 0 or have a bias argument
                 {
+                    unsigned int mandatoryArgumentCount = 2;   // All functions have sampler and coordinate arguments
+
+                    if (textureFunction.offset)
+                    {
+                        mandatoryArgumentCount++;
+                    }
+
+                    bool bias = (arguments.size() > mandatoryArgumentCount);   // Bias argument is optional
+
                     if (lod0 || mContext.shaderType == SH_VERTEX_SHADER)
                     {
-                        textureFunction.method = TextureFunction::LOD0;
+                        if (bias)
+                        {
+                            textureFunction.method = TextureFunction::LOD0BIAS;
+                        }
+                        else
+                        {
+                            textureFunction.method = TextureFunction::LOD0;
+                        }
                     }
-                    else
+                    else if (bias)
                     {
-                        unsigned int mandatoryArgumentCount = 2;   // All functions have sampler and coordinate arguments
-
-                        if (textureFunction.offset)
-                        {
-                            mandatoryArgumentCount++;
-                        }
-
-                        if (arguments.size() > mandatoryArgumentCount)   // Bias argument is optional
-                        {
-                            textureFunction.method = TextureFunction::BIAS;
-                        }
+                        textureFunction.method = TextureFunction::BIAS;
                     }
                 }
 
                 mUsesTexture.insert(textureFunction);
-                
+
                 out << textureFunction.name();
             }
-            
+
             for (TIntermSequence::iterator arg = arguments.begin(); arg != arguments.end(); arg++)
             {
                 if (mOutputType == SH_HLSL11_OUTPUT && IsSampler((*arg)->getAsTyped()->getBasicType()))
diff --git a/src/compiler/translator/OutputHLSL.h b/src/compiler/translator/OutputHLSL.h
index 283e217..5d66fc5 100644
--- a/src/compiler/translator/OutputHLSL.h
+++ b/src/compiler/translator/OutputHLSL.h
@@ -104,6 +104,7 @@
             BIAS,
             LOD,
             LOD0,
+            LOD0BIAS,
             SIZE,   // textureSize()
             FETCH,
             GRAD