mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-20 18:29:23 +00:00
Add maxAnisotropy to GPUSamplerDescriptor
Adds some maxAnisotropy implementation. Adds an end2end test, drawing a slanted plane with a texture of which each mipmap has a different color, with different maxAnisotropy values. You can get an idea of what it does at https://jsfiddle.net/t64kpu81/85/ Needs further CTS. Bug: dawn:568 Change-Id: I89ac56d8cf0fbb655358bf6effa016ddc1f8426f Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/35143 Commit-Queue: Kai Ninomiya <kainino@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
c08276644f
commit
f8c5e4ab74
@@ -20,6 +20,12 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace {
|
||||
uint16_t GetClampedMaxAnisotropy(uint16_t value) {
|
||||
return value >= 1u ? value : 1u;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
namespace dawn_native {
|
||||
|
||||
MaybeError ValidateSamplerDescriptor(DeviceBase*, const SamplerDescriptor* descriptor) {
|
||||
@@ -40,6 +46,16 @@ namespace dawn_native {
|
||||
"Min lod clamp value cannot greater than max lod clamp value");
|
||||
}
|
||||
|
||||
if (descriptor->maxAnisotropy > 1) {
|
||||
if (descriptor->minFilter != wgpu::FilterMode::Linear ||
|
||||
descriptor->magFilter != wgpu::FilterMode::Linear ||
|
||||
descriptor->mipmapFilter != wgpu::FilterMode::Linear) {
|
||||
return DAWN_VALIDATION_ERROR(
|
||||
"min, mag, and mipmap filter should be linear when using anisotropic "
|
||||
"filtering");
|
||||
}
|
||||
}
|
||||
|
||||
DAWN_TRY(ValidateFilterMode(descriptor->minFilter));
|
||||
DAWN_TRY(ValidateFilterMode(descriptor->magFilter));
|
||||
DAWN_TRY(ValidateFilterMode(descriptor->mipmapFilter));
|
||||
@@ -62,7 +78,8 @@ namespace dawn_native {
|
||||
mMipmapFilter(descriptor->mipmapFilter),
|
||||
mLodMinClamp(descriptor->lodMinClamp),
|
||||
mLodMaxClamp(descriptor->lodMaxClamp),
|
||||
mCompareFunction(descriptor->compare) {
|
||||
mCompareFunction(descriptor->compare),
|
||||
mMaxAnisotropy(GetClampedMaxAnisotropy(descriptor->maxAnisotropy)) {
|
||||
}
|
||||
|
||||
SamplerBase::SamplerBase(DeviceBase* device, ObjectBase::ErrorTag tag)
|
||||
@@ -87,7 +104,8 @@ namespace dawn_native {
|
||||
size_t SamplerBase::ComputeContentHash() {
|
||||
ObjectContentHasher recorder;
|
||||
recorder.Record(mAddressModeU, mAddressModeV, mAddressModeW, mMagFilter, mMinFilter,
|
||||
mMipmapFilter, mLodMinClamp, mLodMaxClamp, mCompareFunction);
|
||||
mMipmapFilter, mLodMinClamp, mLodMaxClamp, mCompareFunction,
|
||||
mMaxAnisotropy);
|
||||
return recorder.GetContentHash();
|
||||
}
|
||||
|
||||
@@ -105,7 +123,7 @@ namespace dawn_native {
|
||||
a->mAddressModeW == b->mAddressModeW && a->mMagFilter == b->mMagFilter &&
|
||||
a->mMinFilter == b->mMinFilter && a->mMipmapFilter == b->mMipmapFilter &&
|
||||
a->mLodMinClamp == b->mLodMinClamp && a->mLodMaxClamp == b->mLodMaxClamp &&
|
||||
a->mCompareFunction == b->mCompareFunction;
|
||||
a->mCompareFunction == b->mCompareFunction && a->mMaxAnisotropy == b->mMaxAnisotropy;
|
||||
}
|
||||
|
||||
} // namespace dawn_native
|
||||
|
||||
@@ -42,6 +42,10 @@ namespace dawn_native {
|
||||
bool operator()(const SamplerBase* a, const SamplerBase* b) const;
|
||||
};
|
||||
|
||||
uint16_t GetMaxAnisotropy() const {
|
||||
return mMaxAnisotropy;
|
||||
}
|
||||
|
||||
private:
|
||||
SamplerBase(DeviceBase* device, ObjectBase::ErrorTag tag);
|
||||
|
||||
@@ -55,6 +59,7 @@ namespace dawn_native {
|
||||
float mLodMinClamp;
|
||||
float mLodMaxClamp;
|
||||
wgpu::CompareFunction mCompareFunction;
|
||||
uint16_t mMaxAnisotropy;
|
||||
};
|
||||
|
||||
} // namespace dawn_native
|
||||
|
||||
@@ -69,13 +69,21 @@ namespace dawn_native { namespace d3d12 {
|
||||
? D3D12_FILTER_REDUCTION_TYPE_STANDARD
|
||||
: D3D12_FILTER_REDUCTION_TYPE_COMPARISON;
|
||||
|
||||
mSamplerDesc.Filter =
|
||||
D3D12_ENCODE_BASIC_FILTER(minFilter, magFilter, mipmapFilter, reduction);
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_sampler_desc
|
||||
mSamplerDesc.MaxAnisotropy = std::min<uint16_t>(GetMaxAnisotropy(), 16u);
|
||||
|
||||
if (mSamplerDesc.MaxAnisotropy > 1) {
|
||||
mSamplerDesc.Filter = D3D12_ENCODE_ANISOTROPIC_FILTER(reduction);
|
||||
} else {
|
||||
mSamplerDesc.Filter =
|
||||
D3D12_ENCODE_BASIC_FILTER(minFilter, magFilter, mipmapFilter, reduction);
|
||||
}
|
||||
|
||||
mSamplerDesc.AddressU = AddressMode(descriptor->addressModeU);
|
||||
mSamplerDesc.AddressV = AddressMode(descriptor->addressModeV);
|
||||
mSamplerDesc.AddressW = AddressMode(descriptor->addressModeW);
|
||||
mSamplerDesc.MipLODBias = 0.f;
|
||||
mSamplerDesc.MaxAnisotropy = 1;
|
||||
|
||||
if (descriptor->compare != wgpu::CompareFunction::Undefined) {
|
||||
mSamplerDesc.ComparisonFunc = ToD3D12ComparisonFunc(descriptor->compare);
|
||||
} else {
|
||||
|
||||
@@ -75,6 +75,8 @@ namespace dawn_native { namespace metal {
|
||||
|
||||
mtlDesc.lodMinClamp = descriptor->lodMinClamp;
|
||||
mtlDesc.lodMaxClamp = descriptor->lodMaxClamp;
|
||||
// https://developer.apple.com/documentation/metal/mtlsamplerdescriptor/1516164-maxanisotropy
|
||||
mtlDesc.maxAnisotropy = std::min<uint16_t>(GetMaxAnisotropy(), 16u);
|
||||
|
||||
if (descriptor->compare != wgpu::CompareFunction::Undefined) {
|
||||
// Sampler compare is unsupported before A9, which we validate in
|
||||
|
||||
@@ -82,7 +82,8 @@ namespace dawn_native { namespace opengl {
|
||||
void Sampler::SetupGLSampler(GLuint sampler,
|
||||
const SamplerDescriptor* descriptor,
|
||||
bool forceNearest) {
|
||||
const OpenGLFunctions& gl = ToBackend(GetDevice())->gl;
|
||||
Device* device = ToBackend(GetDevice());
|
||||
const OpenGLFunctions& gl = device->gl;
|
||||
|
||||
if (forceNearest) {
|
||||
gl.SamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
@@ -105,6 +106,11 @@ namespace dawn_native { namespace opengl {
|
||||
gl.SamplerParameteri(sampler, GL_TEXTURE_COMPARE_FUNC,
|
||||
ToOpenGLCompareFunction(descriptor->compare));
|
||||
}
|
||||
|
||||
if (gl.IsAtLeastGL(4, 6) ||
|
||||
gl.IsGLExtensionSupported("GL_EXT_texture_filter_anisotropic")) {
|
||||
gl.SamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY, GetMaxAnisotropy());
|
||||
}
|
||||
}
|
||||
|
||||
GLuint Sampler::GetFilteringHandle() const {
|
||||
|
||||
@@ -316,6 +316,10 @@ namespace dawn_native { namespace vulkan {
|
||||
mComputeSubgroupSize = FindComputeSubgroupSize();
|
||||
}
|
||||
|
||||
if (mDeviceInfo.features.samplerAnisotropy == VK_TRUE) {
|
||||
usedKnobs.features.samplerAnisotropy = VK_TRUE;
|
||||
}
|
||||
|
||||
if (IsExtensionEnabled(Extension::TextureCompressionBC)) {
|
||||
ASSERT(ToBackend(GetAdapter())->GetDeviceInfo().features.textureCompressionBC ==
|
||||
VK_TRUE);
|
||||
|
||||
@@ -71,8 +71,6 @@ namespace dawn_native { namespace vulkan {
|
||||
createInfo.addressModeV = VulkanSamplerAddressMode(descriptor->addressModeV);
|
||||
createInfo.addressModeW = VulkanSamplerAddressMode(descriptor->addressModeW);
|
||||
createInfo.mipLodBias = 0.0f;
|
||||
createInfo.anisotropyEnable = VK_FALSE;
|
||||
createInfo.maxAnisotropy = 1.0f;
|
||||
if (descriptor->compare != wgpu::CompareFunction::Undefined) {
|
||||
createInfo.compareOp = ToVulkanCompareOp(descriptor->compare);
|
||||
createInfo.compareEnable = VK_TRUE;
|
||||
@@ -86,6 +84,18 @@ namespace dawn_native { namespace vulkan {
|
||||
createInfo.unnormalizedCoordinates = VK_FALSE;
|
||||
|
||||
Device* device = ToBackend(GetDevice());
|
||||
uint16_t maxAnisotropy = GetMaxAnisotropy();
|
||||
if (device->GetDeviceInfo().features.samplerAnisotropy == VK_TRUE && maxAnisotropy > 1) {
|
||||
createInfo.anisotropyEnable = VK_TRUE;
|
||||
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkSamplerCreateInfo.html
|
||||
createInfo.maxAnisotropy =
|
||||
std::min(static_cast<float>(maxAnisotropy),
|
||||
device->GetDeviceInfo().properties.limits.maxSamplerAnisotropy);
|
||||
} else {
|
||||
createInfo.anisotropyEnable = VK_FALSE;
|
||||
createInfo.maxAnisotropy = 1;
|
||||
}
|
||||
|
||||
return CheckVkSuccess(
|
||||
device->fn.CreateSampler(device->GetVkDevice(), &createInfo, nullptr, &*mHandle),
|
||||
"CreateSampler");
|
||||
|
||||
Reference in New Issue
Block a user