• 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/Sampler.h"
16 
17 #include "dawn_native/Device.h"
18 #include "dawn_native/ObjectContentHasher.h"
19 #include "dawn_native/ValidationUtils_autogen.h"
20 
21 #include <cmath>
22 
23 namespace dawn_native {
24 
ValidateSamplerDescriptor(DeviceBase *,const SamplerDescriptor * descriptor)25     MaybeError ValidateSamplerDescriptor(DeviceBase*, const SamplerDescriptor* descriptor) {
26         DAWN_INVALID_IF(descriptor->nextInChain != nullptr, "nextInChain must be nullptr");
27 
28         DAWN_INVALID_IF(std::isnan(descriptor->lodMinClamp) || std::isnan(descriptor->lodMaxClamp),
29                         "LOD clamp bounds [%f, %f] contain a NaN.", descriptor->lodMinClamp,
30                         descriptor->lodMaxClamp);
31 
32         DAWN_INVALID_IF(descriptor->lodMinClamp < 0 || descriptor->lodMaxClamp < 0,
33                         "LOD clamp bounds [%f, %f] contain contain a negative number.",
34                         descriptor->lodMinClamp, descriptor->lodMaxClamp);
35 
36         DAWN_INVALID_IF(descriptor->lodMinClamp > descriptor->lodMaxClamp,
37                         "LOD min clamp (%f) is larger than the max clamp (%f).",
38                         descriptor->lodMinClamp, descriptor->lodMaxClamp);
39 
40         if (descriptor->maxAnisotropy > 1) {
41             DAWN_INVALID_IF(descriptor->minFilter != wgpu::FilterMode::Linear ||
42                                 descriptor->magFilter != wgpu::FilterMode::Linear ||
43                                 descriptor->mipmapFilter != wgpu::FilterMode::Linear,
44                             "One of minFilter (%s), magFilter (%s) or mipmapFilter (%s) is not %s "
45                             "while using anisotropic filter (maxAnisotropy is %f)",
46                             descriptor->magFilter, descriptor->minFilter, descriptor->mipmapFilter,
47                             wgpu::FilterMode::Linear, descriptor->maxAnisotropy);
48         } else if (descriptor->maxAnisotropy == 0u) {
49             return DAWN_FORMAT_VALIDATION_ERROR("Max anisotropy (%f) is less than 1.",
50                                                 descriptor->maxAnisotropy);
51         }
52 
53         DAWN_TRY(ValidateFilterMode(descriptor->minFilter));
54         DAWN_TRY(ValidateFilterMode(descriptor->magFilter));
55         DAWN_TRY(ValidateFilterMode(descriptor->mipmapFilter));
56         DAWN_TRY(ValidateAddressMode(descriptor->addressModeU));
57         DAWN_TRY(ValidateAddressMode(descriptor->addressModeV));
58         DAWN_TRY(ValidateAddressMode(descriptor->addressModeW));
59 
60         // CompareFunction::Undefined is tagged as invalid because it can't be used, except for the
61         // SamplerDescriptor where it is a special value that means the sampler is not a
62         // comparison-sampler.
63         if (descriptor->compare != wgpu::CompareFunction::Undefined) {
64             DAWN_TRY(ValidateCompareFunction(descriptor->compare));
65         }
66 
67         return {};
68     }
69 
70     // SamplerBase
71 
SamplerBase(DeviceBase * device,const SamplerDescriptor * descriptor,ApiObjectBase::UntrackedByDeviceTag tag)72     SamplerBase::SamplerBase(DeviceBase* device,
73                              const SamplerDescriptor* descriptor,
74                              ApiObjectBase::UntrackedByDeviceTag tag)
75         : ApiObjectBase(device, descriptor->label),
76           mAddressModeU(descriptor->addressModeU),
77           mAddressModeV(descriptor->addressModeV),
78           mAddressModeW(descriptor->addressModeW),
79           mMagFilter(descriptor->magFilter),
80           mMinFilter(descriptor->minFilter),
81           mMipmapFilter(descriptor->mipmapFilter),
82           mLodMinClamp(descriptor->lodMinClamp),
83           mLodMaxClamp(descriptor->lodMaxClamp),
84           mCompareFunction(descriptor->compare),
85           mMaxAnisotropy(descriptor->maxAnisotropy) {
86     }
87 
SamplerBase(DeviceBase * device,const SamplerDescriptor * descriptor)88     SamplerBase::SamplerBase(DeviceBase* device, const SamplerDescriptor* descriptor)
89         : SamplerBase(device, descriptor, kUntrackedByDevice) {
90         TrackInDevice();
91     }
92 
SamplerBase(DeviceBase * device)93     SamplerBase::SamplerBase(DeviceBase* device) : ApiObjectBase(device, kLabelNotImplemented) {
94         TrackInDevice();
95     }
96 
SamplerBase(DeviceBase * device,ObjectBase::ErrorTag tag)97     SamplerBase::SamplerBase(DeviceBase* device, ObjectBase::ErrorTag tag)
98         : ApiObjectBase(device, tag) {
99     }
100 
101     SamplerBase::~SamplerBase() = default;
102 
DestroyImpl()103     void SamplerBase::DestroyImpl() {
104         if (IsCachedReference()) {
105             // Do not uncache the actual cached object if we are a blueprint.
106             GetDevice()->UncacheSampler(this);
107         }
108     }
109 
110     // static
MakeError(DeviceBase * device)111     SamplerBase* SamplerBase::MakeError(DeviceBase* device) {
112         return new SamplerBase(device, ObjectBase::kError);
113     }
114 
GetType() const115     ObjectType SamplerBase::GetType() const {
116         return ObjectType::Sampler;
117     }
118 
IsComparison() const119     bool SamplerBase::IsComparison() const {
120         return mCompareFunction != wgpu::CompareFunction::Undefined;
121     }
122 
IsFiltering() const123     bool SamplerBase::IsFiltering() const {
124         return mMinFilter == wgpu::FilterMode::Linear || mMagFilter == wgpu::FilterMode::Linear ||
125                mMipmapFilter == wgpu::FilterMode::Linear;
126     }
127 
ComputeContentHash()128     size_t SamplerBase::ComputeContentHash() {
129         ObjectContentHasher recorder;
130         recorder.Record(mAddressModeU, mAddressModeV, mAddressModeW, mMagFilter, mMinFilter,
131                         mMipmapFilter, mLodMinClamp, mLodMaxClamp, mCompareFunction,
132                         mMaxAnisotropy);
133         return recorder.GetContentHash();
134     }
135 
operator ()(const SamplerBase * a,const SamplerBase * b) const136     bool SamplerBase::EqualityFunc::operator()(const SamplerBase* a, const SamplerBase* b) const {
137         if (a == b) {
138             return true;
139         }
140 
141         ASSERT(!std::isnan(a->mLodMinClamp));
142         ASSERT(!std::isnan(b->mLodMinClamp));
143         ASSERT(!std::isnan(a->mLodMaxClamp));
144         ASSERT(!std::isnan(b->mLodMaxClamp));
145 
146         return a->mAddressModeU == b->mAddressModeU && a->mAddressModeV == b->mAddressModeV &&
147                a->mAddressModeW == b->mAddressModeW && a->mMagFilter == b->mMagFilter &&
148                a->mMinFilter == b->mMinFilter && a->mMipmapFilter == b->mMipmapFilter &&
149                a->mLodMinClamp == b->mLodMinClamp && a->mLodMaxClamp == b->mLodMaxClamp &&
150                a->mCompareFunction == b->mCompareFunction && a->mMaxAnisotropy == b->mMaxAnisotropy;
151     }
152 
153 }  // namespace dawn_native
154