• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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