OpenGL: clamp maxAnisotropy to GL's max.

Clamp the user-provided maxAnisotropy to GL_MAX_TEXTURE_MAX_ANISOTROPY.

From the WebGPU spec: "The used value of maxAnisotropy will be
clamped to the maximum value that the platform supports."

Bug: dawn:2188
Change-Id: I6c7de2663094af5f3861de2d29315091c36dbdc6
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/177181
Commit-Queue: Stephen White <senorblanco@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/dawn/native/opengl/DeviceGL.cpp b/src/dawn/native/opengl/DeviceGL.cpp
index f93f8f6..77a8a42 100644
--- a/src/dawn/native/opengl/DeviceGL.cpp
+++ b/src/dawn/native/opengl/DeviceGL.cpp
@@ -46,6 +46,7 @@
 #include "dawn/native/opengl/SamplerGL.h"
 #include "dawn/native/opengl/ShaderModuleGL.h"
 #include "dawn/native/opengl/TextureGL.h"
+#include "dawn/native/opengl/UtilsGL.h"
 
 namespace {
 
@@ -191,6 +192,9 @@
 
     Ref<Queue> queue;
     DAWN_TRY_ASSIGN(queue, Queue::Create(this, &descriptor->defaultQueue));
+    if (HasAnisotropicFiltering(gl)) {
+        gl.GetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &mMaxTextureMaxAnisotropy);
+    }
     return DeviceBase::Initialize(std::move(queue));
 }
 
@@ -434,4 +438,8 @@
     return mGL;
 }
 
+int Device::GetMaxTextureMaxAnisotropy() const {
+    return mMaxTextureMaxAnisotropy;
+}
+
 }  // namespace dawn::native::opengl
diff --git a/src/dawn/native/opengl/DeviceGL.h b/src/dawn/native/opengl/DeviceGL.h
index 4f99ec2..2ad1e2e 100644
--- a/src/dawn/native/opengl/DeviceGL.h
+++ b/src/dawn/native/opengl/DeviceGL.h
@@ -66,6 +66,8 @@
 
     const GLFormat& GetGLFormat(const Format& format);
 
+    int GetMaxTextureMaxAnisotropy() const;
+
     MaybeError ValidateTextureCanBeWrapped(const UnpackedPtr<TextureDescriptor>& descriptor);
     Ref<TextureBase> CreateTextureWrappingEGLImage(const ExternalImageDescriptor* descriptor,
                                                    ::EGLImage image);
@@ -149,6 +151,7 @@
 
     GLFormatTable mFormatTable;
     std::unique_ptr<Context> mContext = nullptr;
+    int mMaxTextureMaxAnisotropy = 0;
 };
 
 }  // namespace dawn::native::opengl
diff --git a/src/dawn/native/opengl/SamplerGL.cpp b/src/dawn/native/opengl/SamplerGL.cpp
index 7269ada..31ea263 100644
--- a/src/dawn/native/opengl/SamplerGL.cpp
+++ b/src/dawn/native/opengl/SamplerGL.cpp
@@ -27,6 +27,8 @@
 
 #include "dawn/native/opengl/SamplerGL.h"
 
+#include <algorithm>
+
 #include "dawn/common/Assert.h"
 #include "dawn/native/opengl/DeviceGL.h"
 #include "dawn/native/opengl/UtilsGL.h"
@@ -135,8 +137,10 @@
                              ToOpenGLCompareFunction(descriptor->compare));
     }
 
-    if (gl.IsAtLeastGL(4, 6) || gl.IsGLExtensionSupported("GL_EXT_texture_filter_anisotropic")) {
-        gl.SamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY, GetMaxAnisotropy());
+    if (HasAnisotropicFiltering(gl)) {
+        uint16_t value =
+            std::min<uint16_t>(GetMaxAnisotropy(), device->GetMaxTextureMaxAnisotropy());
+        gl.SamplerParameteri(sampler, GL_TEXTURE_MAX_ANISOTROPY, value);
     }
 }
 
diff --git a/src/dawn/native/opengl/UtilsGL.cpp b/src/dawn/native/opengl/UtilsGL.cpp
index a961322..bba1e50 100644
--- a/src/dawn/native/opengl/UtilsGL.cpp
+++ b/src/dawn/native/opengl/UtilsGL.cpp
@@ -163,4 +163,8 @@
     gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, prevDrawFBO);
 }
 
+bool HasAnisotropicFiltering(const OpenGLFunctions& gl) {
+    return gl.IsAtLeastGL(4, 6) || gl.IsGLExtensionSupported("GL_EXT_texture_filter_anisotropic");
+}
+
 }  // namespace dawn::native::opengl
diff --git a/src/dawn/native/opengl/UtilsGL.h b/src/dawn/native/opengl/UtilsGL.h
index debe715..48fc772 100644
--- a/src/dawn/native/opengl/UtilsGL.h
+++ b/src/dawn/native/opengl/UtilsGL.h
@@ -48,7 +48,7 @@
                       GLint dstLevel,
                       const Origin3D& dst,
                       const Extent3D& size);
-
+bool HasAnisotropicFiltering(const OpenGLFunctions& gl);
 }  // namespace dawn::native::opengl
 
 #endif  // SRC_DAWN_NATIVE_OPENGL_UTILSGL_H_
diff --git a/webgpu-cts/compat-expectations.txt b/webgpu-cts/compat-expectations.txt
index 7582e55..9ebd486 100644
--- a/webgpu-cts/compat-expectations.txt
+++ b/webgpu-cts/compat-expectations.txt
@@ -129,9 +129,6 @@
 crbug.com/dawn/2087 webgpu:api,validation,state,device_lost,destroy:createRenderPipelineAsync:valid=false;awaitLost=false [ Failure ]
 crbug.com/dawn/2087 webgpu:api,validation,state,device_lost,destroy:createRenderPipelineAsync:valid=false;awaitLost=true [ Failure ]
 
-# maxAnisotropy failures (OpenGL backend is not clamping maxAnisotropy)
-crbug.com/dawn/2188 webgpu:api,operation,sampling,anisotropy:anisotropic_filter_checkerboard: [ Failure ]
-
 # interpolation "flat" failures
 crbug.com/dawn/2376 webgpu:shader,execution,shader_io,fragment_builtins:inputs,interStage:nearFar=[0,1];sampleCount=1;interpolation={"type":"flat"} [ Failure ]
 crbug.com/dawn/2376 webgpu:shader,execution,shader_io,fragment_builtins:inputs,interStage:nearFar=[0,1];sampleCount=4;interpolation={"type":"flat"} [ Failure ]