1 // Copyright 2017 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "dawn_native/opengl/SamplerGL.h" 16 17 #include "common/Assert.h" 18 #include "dawn_native/opengl/DeviceGL.h" 19 #include "dawn_native/opengl/UtilsGL.h" 20 21 namespace dawn_native { namespace opengl { 22 23 namespace { MagFilterMode(wgpu::FilterMode filter)24 GLenum MagFilterMode(wgpu::FilterMode filter) { 25 switch (filter) { 26 case wgpu::FilterMode::Nearest: 27 return GL_NEAREST; 28 case wgpu::FilterMode::Linear: 29 return GL_LINEAR; 30 } 31 UNREACHABLE(); 32 } 33 MinFilterMode(wgpu::FilterMode minFilter,wgpu::FilterMode mipMapFilter)34 GLenum MinFilterMode(wgpu::FilterMode minFilter, wgpu::FilterMode mipMapFilter) { 35 switch (minFilter) { 36 case wgpu::FilterMode::Nearest: 37 switch (mipMapFilter) { 38 case wgpu::FilterMode::Nearest: 39 return GL_NEAREST_MIPMAP_NEAREST; 40 case wgpu::FilterMode::Linear: 41 return GL_NEAREST_MIPMAP_LINEAR; 42 } 43 case wgpu::FilterMode::Linear: 44 switch (mipMapFilter) { 45 case wgpu::FilterMode::Nearest: 46 return GL_LINEAR_MIPMAP_NEAREST; 47 case wgpu::FilterMode::Linear: 48 return GL_LINEAR_MIPMAP_LINEAR; 49 } 50 } 51 UNREACHABLE(); 52 } 53 WrapMode(wgpu::AddressMode mode)54 GLenum WrapMode(wgpu::AddressMode mode) { 55 switch (mode) { 56 case wgpu::AddressMode::Repeat: 57 return GL_REPEAT; 58 case wgpu::AddressMode::MirrorRepeat: 59 return GL_MIRRORED_REPEAT; 60 case wgpu::AddressMode::ClampToEdge: 61 return GL_CLAMP_TO_EDGE; 62 } 63 UNREACHABLE(); 64 } 65 66 } // namespace 67 Sampler(Device * device,const SamplerDescriptor * descriptor)68 Sampler::Sampler(Device* device, const SamplerDescriptor* descriptor) 69 : SamplerBase(device, descriptor) { 70 const OpenGLFunctions& gl = ToBackend(GetDevice())->gl; 71 72 gl.GenSamplers(1, &mFilteringHandle); 73 SetupGLSampler(mFilteringHandle, descriptor, false); 74 75 gl.GenSamplers(1, &mNonFilteringHandle); 76 SetupGLSampler(mNonFilteringHandle, descriptor, true); 77 } 78 79 Sampler::~Sampler() = default; 80 DestroyImpl()81 void Sampler::DestroyImpl() { 82 SamplerBase::DestroyImpl(); 83 const OpenGLFunctions& gl = ToBackend(GetDevice())->gl; 84 gl.DeleteSamplers(1, &mFilteringHandle); 85 gl.DeleteSamplers(1, &mNonFilteringHandle); 86 } 87 SetupGLSampler(GLuint sampler,const SamplerDescriptor * descriptor,bool forceNearest)88 void Sampler::SetupGLSampler(GLuint sampler, 89 const SamplerDescriptor* descriptor, 90 bool forceNearest) { 91 Device* device = ToBackend(GetDevice()); 92 const OpenGLFunctions& gl = device->gl; 93 94 if (forceNearest) { 95 gl.SamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 96 gl.SamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 97 } else { 98 gl.SamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, 99 MagFilterMode(descriptor->magFilter)); 100 gl.SamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, 101 MinFilterMode(descriptor->minFilter, descriptor->mipmapFilter)); 102 } 103 gl.SamplerParameteri(sampler, GL_TEXTURE_WRAP_R, WrapMode(descriptor->addressModeW)); 104 gl.SamplerParameteri(sampler, GL_TEXTURE_WRAP_S, WrapMode(descriptor->addressModeU)); 105 gl.SamplerParameteri(sampler, GL_TEXTURE_WRAP_T, WrapMode(descriptor->addressModeV)); 106 107 gl.SamplerParameterf(sampler, GL_TEXTURE_MIN_LOD, descriptor->lodMinClamp); 108 gl.SamplerParameterf(sampler, GL_TEXTURE_MAX_LOD, descriptor->lodMaxClamp); 109 110 if (descriptor->compare != wgpu::CompareFunction::Undefined) { 111 gl.SamplerParameteri(sampler, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); 112 gl.SamplerParameteri(sampler, GL_TEXTURE_COMPARE_FUNC, 113 ToOpenGLCompareFunction(descriptor->compare)); 114 } 115 116 if (gl.IsAtLeastGL(4, 6) || 117 gl.IsGLExtensionSupported("GL_EXT_texture_filter_anisotropic")) { 118 gl.SamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY, GetMaxAnisotropy()); 119 } 120 } 121 GetFilteringHandle() const122 GLuint Sampler::GetFilteringHandle() const { 123 return mFilteringHandle; 124 } 125 GetNonFilteringHandle() const126 GLuint Sampler::GetNonFilteringHandle() const { 127 return mNonFilteringHandle; 128 } 129 130 }} // namespace dawn_native::opengl 131