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