diff --git a/src/gui/rhi/qrhid3d12.cpp b/src/gui/rhi/qrhid3d12.cpp index 3e8596bf99..5630aa852b 100644 --- a/src/gui/rhi/qrhid3d12.cpp +++ b/src/gui/rhi/qrhid3d12.cpp @@ -2362,14 +2362,14 @@ void QD3D12SamplerManager::destroy() QD3D12Descriptor QD3D12SamplerManager::getShaderVisibleDescriptor(const D3D12_SAMPLER_DESC &desc) { - auto it = gpuMap.constFind(desc); + auto it = gpuMap.constFind({desc}); if (it != gpuMap.cend()) return *it; QD3D12Descriptor descriptor = shaderVisibleSamplerHeap.heap.get(1); if (descriptor.isValid()) { device->CreateSampler(&desc, descriptor.cpuHandle); - gpuMap.insert(desc, descriptor); + gpuMap.insert({desc}, descriptor); } else { qWarning("Out of shader-visible SAMPLER descriptor heap space," " this should not happen, maximum number of unique samplers is %u", diff --git a/src/gui/rhi/qrhid3d12_p_p.h b/src/gui/rhi/qrhid3d12_p_p.h index 4f1717e2bd..1048e66142 100644 --- a/src/gui/rhi/qrhid3d12_p_p.h +++ b/src/gui/rhi/qrhid3d12_p_p.h @@ -20,6 +20,7 @@ #include "qshaderdescription_p.h" #include #include + #include #include @@ -30,11 +31,6 @@ #include "D3D12MemAlloc.h" -inline size_t qHash(const D3D12_SAMPLER_DESC &s, size_t seed = 0) noexcept -{ - return QT_PREPEND_NAMESPACE(qHashBits)(&s, sizeof(s), seed); -} - QT_BEGIN_NAMESPACE static const int QD3D12_FRAMES_IN_FLIGHT = 2; @@ -457,15 +453,46 @@ struct QD3D12ShaderVisibleDescriptorHeap QD3D12DescriptorHeap perFrameHeapSlice[QD3D12_FRAMES_IN_FLIGHT]; }; -inline bool operator==(const D3D12_SAMPLER_DESC &a, const D3D12_SAMPLER_DESC &b) noexcept +// wrap foreign struct so we can legally supply equality operators and qHash: +struct Q_D3D12_SAMPLER_DESC { - return !memcmp(&a, &b, sizeof(D3D12_SAMPLER_DESC)); -} + D3D12_SAMPLER_DESC desc; -inline bool operator!=(const D3D12_SAMPLER_DESC &a, const D3D12_SAMPLER_DESC &b) noexcept -{ - return !(a == b); -} + friend bool operator==(const Q_D3D12_SAMPLER_DESC &lhs, const Q_D3D12_SAMPLER_DESC &rhs) noexcept + { + return lhs.desc.Filter == rhs.desc.Filter + && lhs.desc.AddressU == rhs.desc.AddressU + && lhs.desc.AddressV == rhs.desc.AddressV + && lhs.desc.AddressW == rhs.desc.AddressW + && lhs.desc.MipLODBias == rhs.desc.MipLODBias + && lhs.desc.MaxAnisotropy == rhs.desc.MaxAnisotropy + && lhs.desc.ComparisonFunc == rhs.desc.ComparisonFunc + // BorderColor is never used, skip it + && lhs.desc.MinLOD == rhs.desc.MinLOD + && lhs.desc.MaxLOD == rhs.desc.MaxLOD; + } + + friend bool operator!=(const Q_D3D12_SAMPLER_DESC &lhs, const Q_D3D12_SAMPLER_DESC &rhs) noexcept + { + return !(lhs == rhs); + } + + friend size_t qHash(const Q_D3D12_SAMPLER_DESC &key, size_t seed = 0) noexcept + { + QtPrivate::QHashCombine hash; + seed = hash(seed, key.desc.Filter); + seed = hash(seed, key.desc.AddressU); + seed = hash(seed, key.desc.AddressV); + seed = hash(seed, key.desc.AddressW); + seed = hash(seed, key.desc.MipLODBias); + seed = hash(seed, key.desc.MaxAnisotropy); + seed = hash(seed, key.desc.ComparisonFunc); + // BorderColor is never used, skip it + seed = hash(seed, key.desc.MinLOD); + seed = hash(seed, key.desc.MaxLOD); + return seed; + } +}; struct QD3D12SamplerManager { @@ -478,7 +505,7 @@ struct QD3D12SamplerManager ID3D12Device *device = nullptr; QD3D12ShaderVisibleDescriptorHeap shaderVisibleSamplerHeap; - QHash gpuMap; + QHash gpuMap; }; enum QD3D12Stage { VS = 0, HS, DS, GS, PS, CS };