diff --git a/src/dawn/native/Adapter.cpp b/src/dawn/native/Adapter.cpp index 2fbdf18dd8..a23b6e101e 100644 --- a/src/dawn/native/Adapter.cpp +++ b/src/dawn/native/Adapter.cpp @@ -71,6 +71,12 @@ MaybeError AdapterBase::Initialize() { mLimits.v1.maxUniformBuffersPerShaderStage = std::min(mLimits.v1.maxUniformBuffersPerShaderStage, kMaxUniformBuffersPerShaderStage); + // Additional enforcement for dependent limits. + mLimits.v1.maxStorageBufferBindingSize = + std::min(mLimits.v1.maxStorageBufferBindingSize, mLimits.v1.maxBufferSize); + mLimits.v1.maxUniformBufferBindingSize = + std::min(mLimits.v1.maxUniformBufferBindingSize, mLimits.v1.maxBufferSize); + return {}; } diff --git a/src/dawn/native/Limits.cpp b/src/dawn/native/Limits.cpp index 98fb4c6d35..3e593aeb18 100644 --- a/src/dawn/native/Limits.cpp +++ b/src/dawn/native/Limits.cpp @@ -68,7 +68,6 @@ X(Alignment, minUniformBufferOffsetAlignment, 256, 256) \ X(Alignment, minStorageBufferOffsetAlignment, 256, 256) \ X(Maximum, maxVertexBuffers, 8, 8) \ - X(Maximum, maxBufferSize, 268435456, 268435456) \ X(Maximum, maxVertexAttributes, 16, 16) \ X(Maximum, maxVertexBufferArrayStride, 2048, 2048) \ X(Maximum, maxInterStageShaderComponents, 60, 60) \ diff --git a/src/dawn/tests/DawnTest.cpp b/src/dawn/tests/DawnTest.cpp index 8c2777fc2a..7b118e83b2 100644 --- a/src/dawn/tests/DawnTest.cpp +++ b/src/dawn/tests/DawnTest.cpp @@ -815,6 +815,12 @@ const wgpu::AdapterProperties& DawnTestBase::GetAdapterProperties() const { return mParam.adapterProperties; } +wgpu::SupportedLimits DawnTestBase::GetAdapterLimits() { + wgpu::SupportedLimits supportedLimits = {}; + mAdapter.GetLimits(&supportedLimits); + return supportedLimits; +} + wgpu::SupportedLimits DawnTestBase::GetSupportedLimits() { wgpu::SupportedLimits supportedLimits = {}; device.GetLimits(&supportedLimits); diff --git a/src/dawn/tests/DawnTest.h b/src/dawn/tests/DawnTest.h index 47046fedc9..a254710252 100644 --- a/src/dawn/tests/DawnTest.h +++ b/src/dawn/tests/DawnTest.h @@ -564,6 +564,7 @@ class DawnTestBase { const wgpu::AdapterProperties& GetAdapterProperties() const; + wgpu::SupportedLimits GetAdapterLimits(); wgpu::SupportedLimits GetSupportedLimits(); private: diff --git a/src/dawn/tests/end2end/MaxLimitTests.cpp b/src/dawn/tests/end2end/MaxLimitTests.cpp index a603db848b..696f0a1d2a 100644 --- a/src/dawn/tests/end2end/MaxLimitTests.cpp +++ b/src/dawn/tests/end2end/MaxLimitTests.cpp @@ -113,8 +113,6 @@ TEST_P(MaxLimitTests, MaxBufferBindingSize) { // TODO(dawn:1549) Fails on Qualcomm-based Android devices. DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsQualcomm()); - // TODO(crbug.com/dawn/1683) Fails on MacBook Pro 2019 - DAWN_SUPPRESS_TEST_IF(IsMacOS() && IsMetal() && IsAMD()); for (wgpu::BufferUsage usage : {wgpu::BufferUsage::Storage, wgpu::BufferUsage::Uniform}) { uint64_t maxBufferBindingSize; @@ -136,6 +134,7 @@ TEST_P(MaxLimitTests, MaxBufferBindingSize) { maxBufferBindingSize = std::min(maxBufferBindingSize, uint64_t(512) * 1024 * 1024); } + maxBufferBindingSize = Align(maxBufferBindingSize - 3u, 4); shader = R"( struct Buf { values : array @@ -162,6 +161,7 @@ TEST_P(MaxLimitTests, MaxBufferBindingSize) { // Clamp to not exceed the maximum i32 value for the WGSL @size(x) annotation. maxBufferBindingSize = std::min(maxBufferBindingSize, uint64_t(std::numeric_limits::max()) + 8); + maxBufferBindingSize = Align(maxBufferBindingSize - 3u, 4); shader = R"( struct Buf { @@ -194,8 +194,7 @@ TEST_P(MaxLimitTests, MaxBufferBindingSize) { device.PushErrorScope(wgpu::ErrorFilter::OutOfMemory); wgpu::BufferDescriptor bufDesc; - uint64_t bufferSize = Align(maxBufferBindingSize - 3u, 4); - bufDesc.size = bufferSize; + bufDesc.size = maxBufferBindingSize; bufDesc.usage = usage | wgpu::BufferUsage::CopyDst; wgpu::Buffer buffer = device.CreateBuffer(&bufDesc); @@ -216,7 +215,7 @@ TEST_P(MaxLimitTests, MaxBufferBindingSize) { queue.WriteBuffer(buffer, 0, &value0, sizeof(value0)); uint32_t value1 = 234; - uint64_t value1Offset = Align(bufferSize - sizeof(value1), 4); + uint64_t value1Offset = Align(maxBufferBindingSize - sizeof(value1), 4); queue.WriteBuffer(buffer, value1Offset, &value1, sizeof(value1)); wgpu::ComputePipelineDescriptor csDesc; @@ -237,9 +236,10 @@ TEST_P(MaxLimitTests, MaxBufferBindingSize) { queue.Submit(1, &commands); EXPECT_BUFFER_U32_EQ(value0, resultBuffer, 0) - << "maxBufferBindingSize=" << bufferSize << "; offset=" << 0 << "; usage=" << usage; + << "maxBufferBindingSize=" << maxBufferBindingSize << "; offset=" << 0 + << "; usage=" << usage; EXPECT_BUFFER_U32_EQ(value1, resultBuffer, 4) - << "maxBufferBindingSize=" << bufferSize << "; offset=" << value1Offset + << "maxBufferBindingSize=" << maxBufferBindingSize << "; offset=" << value1Offset << "; usage=" << usage; } } @@ -540,6 +540,23 @@ TEST_P(MaxLimitTests, ReallyLargeBindGroup) { EXPECT_BUFFER_U32_EQ(1, result, 0); } +// Verifies that supported buffer limits do not exceed maxBufferSize. +TEST_P(MaxLimitTests, MaxBufferSizes) { + // Base limits without tiering. + wgpu::Limits baseLimits = GetAdapterLimits().limits; + EXPECT_LE(baseLimits.maxStorageBufferBindingSize, baseLimits.maxBufferSize); + EXPECT_LE(baseLimits.maxUniformBufferBindingSize, baseLimits.maxBufferSize); + + // Base limits eith tiering. + GetAdapter().SetUseTieredLimits(true); + wgpu::Limits tieredLimits = GetAdapterLimits().limits; + EXPECT_LE(tieredLimits.maxStorageBufferBindingSize, tieredLimits.maxBufferSize); + EXPECT_LE(tieredLimits.maxUniformBufferBindingSize, tieredLimits.maxBufferSize); + + // Unset tiered limit usage to avoid affecting other tests. + GetAdapter().SetUseTieredLimits(false); +} + DAWN_INSTANTIATE_TEST(MaxLimitTests, D3D12Backend(), MetalBackend(),