Complete the sampler object to match WebGPU

WebGPUSampler is much more complete than Dawn's Sampler.
This patch implement the missing part.

BUG=dawn:47

Change-Id: Ief45cb9710493e9d79ddab60fe3be5a123b76ebd
Reviewed-on: https://dawn-review.googlesource.com/c/3540
Commit-Queue: Shaobo Yan <shaobo.yan@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index cd0ba6c..72858ae 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -474,6 +474,8 @@
       "src/dawn_native/d3d12/TextureCopySplitter.h",
       "src/dawn_native/d3d12/TextureD3D12.cpp",
       "src/dawn_native/d3d12/TextureD3D12.h",
+      "src/dawn_native/d3d12/UtilsD3D12.cpp",
+      "src/dawn_native/d3d12/UtilsD3D12.h",
       "src/dawn_native/d3d12/d3d12_platform.h",
     ]
   }
@@ -512,6 +514,8 @@
       "src/dawn_native/metal/SwapChainMTL.mm",
       "src/dawn_native/metal/TextureMTL.h",
       "src/dawn_native/metal/TextureMTL.mm",
+      "src/dawn_native/metal/UtilsMetal.h",
+      "src/dawn_native/metal/UtilsMetal.mm",
     ]
   }
 
@@ -554,6 +558,8 @@
       "src/dawn_native/opengl/SwapChainGL.h",
       "src/dawn_native/opengl/TextureGL.cpp",
       "src/dawn_native/opengl/TextureGL.h",
+      "src/dawn_native/opengl/UtilsGL.cpp",
+      "src/dawn_native/opengl/UtilsGL.h",
     ]
   }
 
@@ -601,6 +607,8 @@
       "src/dawn_native/vulkan/SwapChainVk.h",
       "src/dawn_native/vulkan/TextureVk.cpp",
       "src/dawn_native/vulkan/TextureVk.h",
+      "src/dawn_native/vulkan/UtilsVulkan.cpp",
+      "src/dawn_native/vulkan/UtilsVulkan.h",
       "src/dawn_native/vulkan/VulkanFunctions.cpp",
       "src/dawn_native/vulkan/VulkanFunctions.h",
       "src/dawn_native/vulkan/VulkanInfo.cpp",
diff --git a/dawn.json b/dawn.json
index 1d09f1a..44b9814 100644
--- a/dawn.json
+++ b/dawn.json
@@ -17,9 +17,10 @@
     "address mode": {
         "category": "enum",
         "values": [
-            {"value": 0, "name":"repeat"},
-            {"value": 1, "name":"mirrored repeat"},
-            {"value": 2, "name":"clamp to edge"}
+            {"value": 0, "name": "repeat"},
+            {"value": 1, "name": "mirrored repeat"},
+            {"value": 2, "name": "clamp to edge"},
+            {"value": 3, "name": "clamp to border color"}
         ]
     },
     "attachment descriptor": {
@@ -132,6 +133,14 @@
     "bool": {
         "category": "native"
     },
+    "border color": {
+        "category": "enum",
+        "values": [
+            {"value": 0, "name": "transparent black"},
+            {"value": 1, "name": "opaque black"},
+            {"value": 2, "name": "opaque white"}
+        ]
+    },
     "builder error status": {
         "category": "enum",
         "values": [
@@ -870,12 +879,16 @@
         "category": "structure",
         "extensible": true,
         "members": [
+            {"name": "address mode u", "type": "address mode"},
+            {"name": "address mode v", "type": "address mode"},
+            {"name": "address mode w", "type": "address mode"},
             {"name": "mag filter", "type": "filter mode"},
             {"name": "min filter", "type": "filter mode"},
             {"name": "mipmap filter", "type": "filter mode"},
-            {"name": "address mode u", "type": "address mode"},
-            {"name": "address mode v", "type": "address mode"},
-            {"name": "address mode w", "type": "address mode"}
+            {"name": "lod min clamp", "type": "float"},
+            {"name": "lod max clamp", "type": "float"},
+            {"name": "compare function", "type": "compare function"},
+            {"name": "border color", "type": "border color"}
         ]
     },
     "shader module": {
diff --git a/src/common/Constants.h b/src/common/Constants.h
index 869cb13..238d0c2 100644
--- a/src/common/Constants.h
+++ b/src/common/Constants.h
@@ -27,4 +27,8 @@
 static constexpr uint32_t kMaxColorAttachments = 4u;
 static constexpr uint32_t kTextureRowPitchAlignment = 256u;
 
+// Non spec defined constants.
+static constexpr float kLodMin = 0.0;
+static constexpr float kLodMax = 1000.0;
+
 #endif  // COMMON_CONSTANTS_H_
diff --git a/src/dawn_native/Sampler.cpp b/src/dawn_native/Sampler.cpp
index 71cca99..3e68894 100644
--- a/src/dawn_native/Sampler.cpp
+++ b/src/dawn_native/Sampler.cpp
@@ -23,12 +23,24 @@
         if (descriptor->nextInChain != nullptr) {
             return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
         }
+
+        if (descriptor->lodMinClamp < 0 || descriptor->lodMaxClamp < 0) {
+            return DAWN_VALIDATION_ERROR("LOD must be positive");
+        }
+
+        if (descriptor->lodMinClamp > descriptor->lodMaxClamp) {
+            return DAWN_VALIDATION_ERROR(
+                "Min lod clamp value cannot greater than max lod clamp value");
+        }
+
         DAWN_TRY(ValidateFilterMode(descriptor->minFilter));
         DAWN_TRY(ValidateFilterMode(descriptor->magFilter));
         DAWN_TRY(ValidateFilterMode(descriptor->mipmapFilter));
         DAWN_TRY(ValidateAddressMode(descriptor->addressModeU));
         DAWN_TRY(ValidateAddressMode(descriptor->addressModeV));
         DAWN_TRY(ValidateAddressMode(descriptor->addressModeW));
+        DAWN_TRY(ValidateCompareFunction(descriptor->compareFunction));
+        DAWN_TRY(ValidateBorderColor(descriptor->borderColor));
         return {};
     }
 
diff --git a/src/dawn_native/d3d12/SamplerD3D12.cpp b/src/dawn_native/d3d12/SamplerD3D12.cpp
index 9c3559c..4b78c6c 100644
--- a/src/dawn_native/d3d12/SamplerD3D12.cpp
+++ b/src/dawn_native/d3d12/SamplerD3D12.cpp
@@ -15,6 +15,7 @@
 #include "dawn_native/d3d12/SamplerD3D12.h"
 
 #include "dawn_native/d3d12/DeviceD3D12.h"
+#include "dawn_native/d3d12/UtilsD3D12.h"
 
 namespace dawn_native { namespace d3d12 {
 
@@ -27,6 +28,8 @@
                     return D3D12_TEXTURE_ADDRESS_MODE_MIRROR;
                 case dawn::AddressMode::ClampToEdge:
                     return D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
+                case dawn::AddressMode::ClampToBorderColor:
+                    return D3D12_TEXTURE_ADDRESS_MODE_BORDER;
                 default:
                     UNREACHABLE();
             }
@@ -82,11 +85,27 @@
         mSamplerDesc.AddressW = AddressMode(descriptor->addressModeW);
         mSamplerDesc.MipLODBias = 0.f;
         mSamplerDesc.MaxAnisotropy = 1;
-        mSamplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
-        mSamplerDesc.BorderColor[0] = mSamplerDesc.BorderColor[1] = mSamplerDesc.BorderColor[2] =
-            mSamplerDesc.BorderColor[3] = 0;
-        mSamplerDesc.MinLOD = 0;
-        mSamplerDesc.MaxLOD = D3D12_FLOAT32_MAX;
+        mSamplerDesc.ComparisonFunc = ToD3D12ComparisonFunc(descriptor->compareFunction);
+        mSamplerDesc.MinLOD = descriptor->lodMinClamp;
+        mSamplerDesc.MaxLOD = descriptor->lodMaxClamp;
+
+        switch (descriptor->borderColor) {
+            case dawn::BorderColor::TransparentBlack:
+                mSamplerDesc.BorderColor[0] = mSamplerDesc.BorderColor[1] =
+                    mSamplerDesc.BorderColor[2] = mSamplerDesc.BorderColor[3] = 0;
+                break;
+            case dawn::BorderColor::OpaqueBlack:
+                mSamplerDesc.BorderColor[0] = mSamplerDesc.BorderColor[1] =
+                    mSamplerDesc.BorderColor[2] = 0;
+                mSamplerDesc.BorderColor[3] = 1;
+                break;
+            case dawn::BorderColor::OpaqueWhite:
+                mSamplerDesc.BorderColor[0] = mSamplerDesc.BorderColor[1] =
+                    mSamplerDesc.BorderColor[2] = mSamplerDesc.BorderColor[3] = 1;
+                break;
+            default:
+                UNREACHABLE();
+        }
     }
 
     const D3D12_SAMPLER_DESC& Sampler::GetSamplerDescriptor() const {
diff --git a/src/dawn_native/d3d12/UtilsD3D12.cpp b/src/dawn_native/d3d12/UtilsD3D12.cpp
new file mode 100644
index 0000000..864605c
--- /dev/null
+++ b/src/dawn_native/d3d12/UtilsD3D12.cpp
@@ -0,0 +1,44 @@
+// Copyright 2019 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "dawn_native/d3d12/UtilsD3D12.h"
+
+#include "common/Assert.h"
+
+namespace dawn_native { namespace d3d12 {
+
+    D3D12_COMPARISON_FUNC ToD3D12ComparisonFunc(dawn::CompareFunction func) {
+        switch (func) {
+            case dawn::CompareFunction::Always:
+                return D3D12_COMPARISON_FUNC_ALWAYS;
+            case dawn::CompareFunction::Equal:
+                return D3D12_COMPARISON_FUNC_EQUAL;
+            case dawn::CompareFunction::Greater:
+                return D3D12_COMPARISON_FUNC_GREATER;
+            case dawn::CompareFunction::GreaterEqual:
+                return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
+            case dawn::CompareFunction::Less:
+                return D3D12_COMPARISON_FUNC_LESS;
+            case dawn::CompareFunction::LessEqual:
+                return D3D12_COMPARISON_FUNC_LESS_EQUAL;
+            case dawn::CompareFunction::Never:
+                return D3D12_COMPARISON_FUNC_NEVER;
+            case dawn::CompareFunction::NotEqual:
+                return D3D12_COMPARISON_FUNC_NOT_EQUAL;
+            default:
+                UNREACHABLE();
+        }
+    }
+
+}}  // namespace dawn_native::d3d12
diff --git a/src/dawn_native/d3d12/UtilsD3D12.h b/src/dawn_native/d3d12/UtilsD3D12.h
new file mode 100644
index 0000000..f47a360
--- /dev/null
+++ b/src/dawn_native/d3d12/UtilsD3D12.h
@@ -0,0 +1,27 @@
+// Copyright 2019 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef DAWNNATIVE_D3D12_UTILSD3D12_H_
+#define DAWNNATIVE_D3D12_UTILSD3D12_H_
+
+#include "dawn_native/d3d12/d3d12_platform.h"
+#include "dawn_native/dawn_platform.h"
+
+namespace dawn_native { namespace d3d12 {
+
+    D3D12_COMPARISON_FUNC ToD3D12ComparisonFunc(dawn::CompareFunction func);
+
+}}  // namespace dawn_native::d3d12
+
+#endif  // DAWNNATIVE_D3D12_UTILSD3D12_H_
diff --git a/src/dawn_native/metal/SamplerMTL.mm b/src/dawn_native/metal/SamplerMTL.mm
index 539431c..19d374b 100644
--- a/src/dawn_native/metal/SamplerMTL.mm
+++ b/src/dawn_native/metal/SamplerMTL.mm
@@ -15,6 +15,7 @@
 #include "dawn_native/metal/SamplerMTL.h"
 
 #include "dawn_native/metal/DeviceMTL.h"
+#include "dawn_native/metal/UtilsMetal.h"
 
 namespace dawn_native { namespace metal {
 
@@ -45,6 +46,19 @@
                     return MTLSamplerAddressModeMirrorRepeat;
                 case dawn::AddressMode::ClampToEdge:
                     return MTLSamplerAddressModeClampToEdge;
+                case dawn::AddressMode::ClampToBorderColor:
+                    return MTLSamplerAddressModeClampToBorderColor;
+            }
+        }
+
+        MTLSamplerBorderColor BorderColor(dawn::BorderColor color) {
+            switch (color) {
+                case dawn::BorderColor::TransparentBlack:
+                    return MTLSamplerBorderColorTransparentBlack;
+                case dawn::BorderColor::OpaqueBlack:
+                    return MTLSamplerBorderColorOpaqueBlack;
+                case dawn::BorderColor::OpaqueWhite:
+                    return MTLSamplerBorderColorOpaqueWhite;
             }
         }
     }
@@ -61,6 +75,11 @@
         mtlDesc.tAddressMode = AddressMode(descriptor->addressModeV);
         mtlDesc.rAddressMode = AddressMode(descriptor->addressModeW);
 
+        mtlDesc.lodMinClamp = descriptor->lodMinClamp;
+        mtlDesc.lodMaxClamp = descriptor->lodMaxClamp;
+        mtlDesc.compareFunction = ToMetalCompareFunction(descriptor->compareFunction);
+        mtlDesc.borderColor = BorderColor(descriptor->borderColor);
+
         mMtlSamplerState = [device->GetMTLDevice() newSamplerStateWithDescriptor:mtlDesc];
     }
 
diff --git a/src/dawn_native/metal/UtilsMetal.h b/src/dawn_native/metal/UtilsMetal.h
new file mode 100644
index 0000000..574036d
--- /dev/null
+++ b/src/dawn_native/metal/UtilsMetal.h
@@ -0,0 +1,28 @@
+// Copyright 2019 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef DAWNNATIVE_METAL_UTILSMETAL_H_
+#define DAWNNATIVE_METAL_UTILSMETAL_H_
+
+#include "dawn_native/dawn_platform.h"
+
+#import <Metal/Metal.h>
+
+namespace dawn_native { namespace metal {
+
+    MTLCompareFunction ToMetalCompareFunction(dawn::CompareFunction compareFunction);
+
+}}  // namespace dawn_native::metal
+
+#endif  // DAWNNATIVE_METAL_UTILSMETAL_H_
diff --git a/src/dawn_native/metal/UtilsMetal.mm b/src/dawn_native/metal/UtilsMetal.mm
new file mode 100644
index 0000000..8621037
--- /dev/null
+++ b/src/dawn_native/metal/UtilsMetal.mm
@@ -0,0 +1,40 @@
+// Copyright 2019 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "dawn_native/metal/UtilsMetal.h"
+
+namespace dawn_native { namespace metal {
+
+    MTLCompareFunction ToMetalCompareFunction(dawn::CompareFunction compareFunction) {
+        switch (compareFunction) {
+            case dawn::CompareFunction::Never:
+                return MTLCompareFunctionNever;
+            case dawn::CompareFunction::Less:
+                return MTLCompareFunctionLess;
+            case dawn::CompareFunction::LessEqual:
+                return MTLCompareFunctionLessEqual;
+            case dawn::CompareFunction::Greater:
+                return MTLCompareFunctionGreater;
+            case dawn::CompareFunction::GreaterEqual:
+                return MTLCompareFunctionGreaterEqual;
+            case dawn::CompareFunction::NotEqual:
+                return MTLCompareFunctionNotEqual;
+            case dawn::CompareFunction::Equal:
+                return MTLCompareFunctionEqual;
+            case dawn::CompareFunction::Always:
+                return MTLCompareFunctionAlways;
+        }
+    }
+
+}}  // namespace dawn_native::metal
diff --git a/src/dawn_native/opengl/SamplerGL.cpp b/src/dawn_native/opengl/SamplerGL.cpp
index ebf4757..cb2e0df 100644
--- a/src/dawn_native/opengl/SamplerGL.cpp
+++ b/src/dawn_native/opengl/SamplerGL.cpp
@@ -16,6 +16,7 @@
 
 #include "common/Assert.h"
 #include "dawn_native/opengl/DeviceGL.h"
+#include "dawn_native/opengl/UtilsGL.h"
 
 namespace dawn_native { namespace opengl {
 
@@ -64,11 +65,17 @@
                     return GL_MIRRORED_REPEAT;
                 case dawn::AddressMode::ClampToEdge:
                     return GL_CLAMP_TO_EDGE;
+                case dawn::AddressMode::ClampToBorderColor:
+                    return GL_CLAMP_TO_BORDER;
                 default:
                     UNREACHABLE();
             }
         }
 
+        static const float kTransparentBlack[4] = {0.0, 0.0, 0.0, 0.0};
+        static const float kOpaqueBlack[4] = {0.0, 0.0, 0.0, 1.0};
+        static const float kOpaqueWhite[4] = {1.0, 1.0, 1.0, 1.0};
+
     }  // namespace
 
     Sampler::Sampler(Device* device, const SamplerDescriptor* descriptor)
@@ -80,6 +87,29 @@
         glSamplerParameteri(mHandle, GL_TEXTURE_WRAP_R, WrapMode(descriptor->addressModeW));
         glSamplerParameteri(mHandle, GL_TEXTURE_WRAP_S, WrapMode(descriptor->addressModeU));
         glSamplerParameteri(mHandle, GL_TEXTURE_WRAP_T, WrapMode(descriptor->addressModeV));
+
+        glSamplerParameterf(mHandle, GL_TEXTURE_MIN_LOD, descriptor->lodMinClamp);
+        glSamplerParameterf(mHandle, GL_TEXTURE_MAX_LOD, descriptor->lodMaxClamp);
+
+        if (ToOpenGLCompareFunction(descriptor->compareFunction) != GL_NEVER) {
+            glSamplerParameteri(mHandle, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
+            glSamplerParameteri(mHandle, GL_TEXTURE_COMPARE_FUNC,
+                                ToOpenGLCompareFunction(descriptor->compareFunction));
+        }
+
+        switch (descriptor->borderColor) {
+            case dawn::BorderColor::TransparentBlack:
+                glSamplerParameterfv(mHandle, GL_TEXTURE_BORDER_COLOR, kTransparentBlack);
+                break;
+            case dawn::BorderColor::OpaqueBlack:
+                glSamplerParameterfv(mHandle, GL_TEXTURE_BORDER_COLOR, kOpaqueBlack);
+                break;
+            case dawn::BorderColor::OpaqueWhite:
+                glSamplerParameterfv(mHandle, GL_TEXTURE_BORDER_COLOR, kOpaqueWhite);
+                break;
+            default:
+                UNREACHABLE();
+        }
     }
 
     GLuint Sampler::GetHandle() const {
diff --git a/src/dawn_native/opengl/UtilsGL.cpp b/src/dawn_native/opengl/UtilsGL.cpp
new file mode 100644
index 0000000..0419d4b
--- /dev/null
+++ b/src/dawn_native/opengl/UtilsGL.cpp
@@ -0,0 +1,44 @@
+// Copyright 2019 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "dawn_native/opengl/UtilsGL.h"
+
+#include "common/Assert.h"
+
+namespace dawn_native { namespace opengl {
+
+    GLuint ToOpenGLCompareFunction(dawn::CompareFunction compareFunction) {
+        switch (compareFunction) {
+            case dawn::CompareFunction::Never:
+                return GL_NEVER;
+            case dawn::CompareFunction::Less:
+                return GL_LESS;
+            case dawn::CompareFunction::LessEqual:
+                return GL_LEQUAL;
+            case dawn::CompareFunction::Greater:
+                return GL_GREATER;
+            case dawn::CompareFunction::GreaterEqual:
+                return GL_GEQUAL;
+            case dawn::CompareFunction::NotEqual:
+                return GL_NOTEQUAL;
+            case dawn::CompareFunction::Equal:
+                return GL_EQUAL;
+            case dawn::CompareFunction::Always:
+                return GL_ALWAYS;
+            default:
+                UNREACHABLE();
+        }
+    }
+
+}}  // namespace dawn_native::opengl
diff --git a/src/dawn_native/opengl/UtilsGL.h b/src/dawn_native/opengl/UtilsGL.h
new file mode 100644
index 0000000..f82eb28
--- /dev/null
+++ b/src/dawn_native/opengl/UtilsGL.h
@@ -0,0 +1,27 @@
+// Copyright 2019 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef DAWNNATIVE_OPENGL_UTILSGL_H_
+#define DAWNNATIVE_OPENGL_UTILSGL_H_
+
+#include "dawn_native/dawn_platform.h"
+#include "glad/glad.h"
+
+namespace dawn_native { namespace opengl {
+
+    GLuint ToOpenGLCompareFunction(dawn::CompareFunction compareFunction);
+
+}}  // namespace dawn_native::opengl
+
+#endif  // DAWNNATIVE_OPENGL_UTILSGL_H_
diff --git a/src/dawn_native/vulkan/SamplerVk.cpp b/src/dawn_native/vulkan/SamplerVk.cpp
index d54f358..aa23b3c 100644
--- a/src/dawn_native/vulkan/SamplerVk.cpp
+++ b/src/dawn_native/vulkan/SamplerVk.cpp
@@ -16,6 +16,7 @@
 
 #include "dawn_native/vulkan/DeviceVk.h"
 #include "dawn_native/vulkan/FencedDeleter.h"
+#include "dawn_native/vulkan/UtilsVulkan.h"
 
 namespace dawn_native { namespace vulkan {
 
@@ -28,6 +29,8 @@
                     return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
                 case dawn::AddressMode::ClampToEdge:
                     return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+                case dawn::AddressMode::ClampToBorderColor:
+                    return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
                 default:
                     UNREACHABLE();
             }
@@ -54,6 +57,19 @@
                     UNREACHABLE();
             }
         }
+
+        VkBorderColor VulkanBorderColor(dawn::BorderColor color) {
+            switch (color) {
+                case dawn::BorderColor::TransparentBlack:
+                    return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
+                case dawn::BorderColor::OpaqueBlack:
+                    return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
+                case dawn::BorderColor::OpaqueWhite:
+                    return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
+                default:
+                    UNREACHABLE();
+            }
+        }
     }  // anonymous namespace
 
     Sampler::Sampler(Device* device, const SamplerDescriptor* descriptor)
@@ -71,11 +87,11 @@
         createInfo.mipLodBias = 0.0f;
         createInfo.anisotropyEnable = VK_FALSE;
         createInfo.maxAnisotropy = 1.0f;
-        createInfo.compareEnable = VK_FALSE;
-        createInfo.compareOp = VK_COMPARE_OP_NEVER;
-        createInfo.minLod = 0.0f;
-        createInfo.maxLod = 1000.0f;
-        createInfo.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
+        createInfo.compareOp = ToVulkanCompareOp(descriptor->compareFunction);
+        createInfo.compareEnable = createInfo.compareOp == VK_COMPARE_OP_NEVER ? VK_FALSE : VK_TRUE;
+        createInfo.minLod = descriptor->lodMinClamp;
+        createInfo.maxLod = descriptor->lodMaxClamp;
+        createInfo.borderColor = VulkanBorderColor(descriptor->borderColor);
         createInfo.unnormalizedCoordinates = VK_FALSE;
 
         if (device->fn.CreateSampler(device->GetVkDevice(), &createInfo, nullptr, &mHandle) !=
diff --git a/src/dawn_native/vulkan/UtilsVulkan.cpp b/src/dawn_native/vulkan/UtilsVulkan.cpp
new file mode 100644
index 0000000..723a6bb
--- /dev/null
+++ b/src/dawn_native/vulkan/UtilsVulkan.cpp
@@ -0,0 +1,44 @@
+// Copyright 2019 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "dawn_native/vulkan/UtilsVulkan.h"
+
+#include "common/Assert.h"
+
+namespace dawn_native { namespace vulkan {
+
+    VkCompareOp ToVulkanCompareOp(dawn::CompareFunction op) {
+        switch (op) {
+            case dawn::CompareFunction::Always:
+                return VK_COMPARE_OP_ALWAYS;
+            case dawn::CompareFunction::Equal:
+                return VK_COMPARE_OP_EQUAL;
+            case dawn::CompareFunction::Greater:
+                return VK_COMPARE_OP_GREATER;
+            case dawn::CompareFunction::GreaterEqual:
+                return VK_COMPARE_OP_GREATER_OR_EQUAL;
+            case dawn::CompareFunction::Less:
+                return VK_COMPARE_OP_LESS;
+            case dawn::CompareFunction::LessEqual:
+                return VK_COMPARE_OP_LESS_OR_EQUAL;
+            case dawn::CompareFunction::Never:
+                return VK_COMPARE_OP_NEVER;
+            case dawn::CompareFunction::NotEqual:
+                return VK_COMPARE_OP_NOT_EQUAL;
+            default:
+                UNREACHABLE();
+        }
+    }
+
+}}  // namespace dawn_native::vulkan
diff --git a/src/dawn_native/vulkan/UtilsVulkan.h b/src/dawn_native/vulkan/UtilsVulkan.h
new file mode 100644
index 0000000..80fa2da
--- /dev/null
+++ b/src/dawn_native/vulkan/UtilsVulkan.h
@@ -0,0 +1,27 @@
+// Copyright 2019 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef DAWNNATIVE_VULKAN_UTILSVULKAN_H_
+#define DAWNNATIVE_VULKAN_UTILSVULKAN_H_
+
+#include "common/vulkan_platform.h"
+#include "dawn_native/dawn_platform.h"
+
+namespace dawn_native { namespace vulkan {
+
+    VkCompareOp ToVulkanCompareOp(dawn::CompareFunction op);
+
+}}  // namespace dawn_native::vulkan
+
+#endif  // DAWNNATIVE_VULKAN_UTILSVULKAN_H_
diff --git a/src/tests/end2end/BindGroupTests.cpp b/src/tests/end2end/BindGroupTests.cpp
index 766f2db..74b6f51 100644
--- a/src/tests/end2end/BindGroupTests.cpp
+++ b/src/tests/end2end/BindGroupTests.cpp
@@ -232,6 +232,11 @@
     samplerDescriptor.addressModeU = dawn::AddressMode::ClampToEdge;
     samplerDescriptor.addressModeV = dawn::AddressMode::ClampToEdge;
     samplerDescriptor.addressModeW = dawn::AddressMode::ClampToEdge;
+    samplerDescriptor.lodMinClamp = kLodMin;
+    samplerDescriptor.lodMaxClamp = kLodMax;
+    samplerDescriptor.compareFunction = dawn::CompareFunction::Never;
+    samplerDescriptor.borderColor = dawn::BorderColor::TransparentBlack;
+
     dawn::Sampler sampler = device.CreateSampler(&samplerDescriptor);
 
     dawn::TextureDescriptor descriptor;
diff --git a/src/tests/end2end/SamplerTests.cpp b/src/tests/end2end/SamplerTests.cpp
index 29c1313..cf98477 100644
--- a/src/tests/end2end/SamplerTests.cpp
+++ b/src/tests/end2end/SamplerTests.cpp
@@ -126,6 +126,10 @@
             descriptor.addressModeU = u.mMode;
             descriptor.addressModeV = v.mMode;
             descriptor.addressModeW = w.mMode;
+            descriptor.lodMinClamp = kLodMin;
+            descriptor.lodMaxClamp = kLodMax;
+            descriptor.compareFunction = dawn::CompareFunction::Never;
+            descriptor.borderColor = dawn::BorderColor::TransparentBlack;
             sampler = device.CreateSampler(&descriptor);
         }
 
diff --git a/src/tests/end2end/TextureViewTests.cpp b/src/tests/end2end/TextureViewTests.cpp
index e005132..ffb9d72 100644
--- a/src/tests/end2end/TextureViewTests.cpp
+++ b/src/tests/end2end/TextureViewTests.cpp
@@ -99,6 +99,10 @@
         samplerDescriptor.addressModeU = kAddressMode;
         samplerDescriptor.addressModeV = kAddressMode;
         samplerDescriptor.addressModeW = kAddressMode;
+        samplerDescriptor.lodMinClamp = kLodMin;
+        samplerDescriptor.lodMaxClamp = kLodMax;
+        samplerDescriptor.compareFunction = dawn::CompareFunction::Never;
+        samplerDescriptor.borderColor = dawn::BorderColor::TransparentBlack;
         mSampler = device.CreateSampler(&samplerDescriptor);
 
         mPipelineLayout = utils::MakeBasicPipelineLayout(device, &mBindGroupLayout);
diff --git a/src/tests/unittests/WireTests.cpp b/src/tests/unittests/WireTests.cpp
index aa08fea..c49abe8 100644
--- a/src/tests/unittests/WireTests.cpp
+++ b/src/tests/unittests/WireTests.cpp
@@ -16,6 +16,7 @@
 #include "mock/mock_dawn.h"
 
 #include "common/Assert.h"
+#include "common/Constants.h"
 #include "dawn_wire/Wire.h"
 #include "utils/TerribleCommandBuffer.h"
 
@@ -496,6 +497,10 @@
     descriptor.addressModeU = DAWN_ADDRESS_MODE_CLAMP_TO_EDGE;
     descriptor.addressModeV = DAWN_ADDRESS_MODE_REPEAT;
     descriptor.addressModeW = DAWN_ADDRESS_MODE_MIRRORED_REPEAT;
+    descriptor.lodMinClamp = kLodMin;
+    descriptor.lodMaxClamp = kLodMax;
+    descriptor.compareFunction = DAWN_COMPARE_FUNCTION_NEVER;
+    descriptor.borderColor = DAWN_BORDER_COLOR_TRANSPARENT_BLACK;
 
     dawnDeviceCreateSampler(device, &descriptor);
     EXPECT_CALL(api, DeviceCreateSampler(apiDevice, MatchesLambda([](const dawnSamplerDescriptor* desc) -> bool {
@@ -505,7 +510,11 @@
             desc->mipmapFilter == DAWN_FILTER_MODE_LINEAR &&
             desc->addressModeU == DAWN_ADDRESS_MODE_CLAMP_TO_EDGE &&
             desc->addressModeV == DAWN_ADDRESS_MODE_REPEAT &&
-            desc->addressModeW == DAWN_ADDRESS_MODE_MIRRORED_REPEAT;
+            desc->addressModeW == DAWN_ADDRESS_MODE_MIRRORED_REPEAT &&
+            desc->compareFunction == DAWN_COMPARE_FUNCTION_NEVER &&
+            desc->borderColor == DAWN_BORDER_COLOR_TRANSPARENT_BLACK &&
+            desc->lodMinClamp == kLodMin &&
+            desc->lodMaxClamp == kLodMax;
     })))
         .WillOnce(Return(nullptr));
 
diff --git a/src/utils/DawnHelpers.cpp b/src/utils/DawnHelpers.cpp
index bc4bf5c..063e39e 100644
--- a/src/utils/DawnHelpers.cpp
+++ b/src/utils/DawnHelpers.cpp
@@ -15,6 +15,7 @@
 #include "utils/DawnHelpers.h"
 
 #include "common/Assert.h"
+#include "common/Constants.h"
 
 #include <shaderc/shaderc.hpp>
 
@@ -195,6 +196,10 @@
         desc.addressModeU = dawn::AddressMode::Repeat;
         desc.addressModeV = dawn::AddressMode::Repeat;
         desc.addressModeW = dawn::AddressMode::Repeat;
+        desc.lodMinClamp = kLodMin;
+        desc.lodMaxClamp = kLodMax;
+        desc.compareFunction = dawn::CompareFunction::Never;
+        desc.borderColor = dawn::BorderColor::TransparentBlack;
 
         return desc;
     }