Dawn: fix limit tiering for maxBufferSize and maxStorageBufferBindingSize

This CL fix an issue related to tiering the maxBufferSize and
maxStorageBufferBindingSize limits. In detail, this CL:
1. Fix the maxStorageBufferBindingSize tiers to [128MB, 1GB, 2GB-4,
   4GB-4] instead of the original last two 2GB-1 and 4GB-1, holding the
   guarantee that maxStorageBufferBindingSize is a multiple of 4 bytes.
2. Add a maxBufferSize tier 4GB, ensuring the guarantee that
   maxStorageBufferBindingSize must be no larger than maxBufferSize in
   case of it tiered to 4GB-4. Previously the largest maxBufferSize tier
   is 2GB, making this guarantee broken after tiering.
3. Move the adapter limits normalization logics in adapter initializing
   to Limits.cpp to allow unittest. Related unittests implemented.
4. Normalize tiered limits to ensure that tiered
   maxStorageBufferBindingSize and maxUniformBufferBindingSize are no
   larger than tiered maxBufferSize. Related unittests implemented.

Issue: dawn:1780
Change-Id: I4821f196fa89c7f18ebbf8e5e45df1c3268db895
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/130120
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Zhaoming Jiang <zhaoming.jiang@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Zhaoming Jiang 2023-05-05 02:14:31 +00:00 committed by Dawn LUCI CQ
parent 90789ea1f8
commit 960918b1b6
4 changed files with 292 additions and 34 deletions

View File

@ -14,9 +14,11 @@
#include "dawn/native/Limits.h" #include "dawn/native/Limits.h"
#include <algorithm>
#include <array> #include <array>
#include "dawn/common/Assert.h" #include "dawn/common/Assert.h"
#include "dawn/common/Constants.h"
#include "dawn/common/Math.h" #include "dawn/common/Math.h"
// clang-format off // clang-format off
@ -35,12 +37,13 @@
X(Maximum, maxComputeWorkgroupSizeZ, 64, 64) \ X(Maximum, maxComputeWorkgroupSizeZ, 64, 64) \
X(Maximum, maxComputeWorkgroupsPerDimension, 65535, 65535) X(Maximum, maxComputeWorkgroupsPerDimension, 65535, 65535)
// Tiers are 128MB, 1GB, 2GB-4, 4GB-4.
#define LIMITS_STORAGE_BUFFER_BINDING_SIZE(X) \ #define LIMITS_STORAGE_BUFFER_BINDING_SIZE(X) \
X(Maximum, maxStorageBufferBindingSize, 134217728, 1073741824, 2147483647, 4294967295) X(Maximum, maxStorageBufferBindingSize, 134217728, 1073741824, 2147483644, 4294967292)
// Tiers are 256Mb, 1Gb, 2Gb. // Tiers are 256MB, 1GB, 2GB, 4GB.
#define LIMITS_MAX_BUFFER_SIZE(X) \ #define LIMITS_MAX_BUFFER_SIZE(X) \
X(Maximum, maxBufferSize, 0x10000000, 0x40000000, 0x80000000) X(Maximum, maxBufferSize, 0x10000000, 0x40000000, 0x80000000, 0x100000000)
// Tiers for limits related to resource bindings. // Tiers for limits related to resource bindings.
// TODO(crbug.com/dawn/685): Define these better. For now, use two tiers where one // TODO(crbug.com/dawn/685): Define these better. For now, use two tiers where one
@ -230,7 +233,18 @@ Limits ApplyLimitTiers(Limits limits) {
} }
LIMITS_EACH_GROUP(X_EACH_GROUP) LIMITS_EACH_GROUP(X_EACH_GROUP)
#undef X_CHECK_BETTER
// After tiering all limit values, enforce additional restriction by calling NormalizeLimits.
// Since maxStorageBufferBindingSize and maxBufferSize tiers are not exactly aligned, it is
// possible that tiered maxStorageBufferBindingSize is larger than tiered maxBufferSize. For
// example, on a hypothetical device with both maxStorageBufferBindingSize and maxBufferSize
// being 4GB-1, the tiered maxStorageBufferBindingSize would be 4GB-4 while the tiered
// maxBufferSize being 2GB. NormalizeLimits will clamp the maxStorageBufferBindingSize to
// maxBufferSize in such cases, although the result may or may not be one of predefined
// maxStorageBufferBindingSize tiers.
NormalizeLimits(&limits);
#undef X_CHECK_BETTER_AND_CLAMP
#undef X_EACH_GROUP #undef X_EACH_GROUP
#undef GET_TIER_COUNT #undef GET_TIER_COUNT
#undef X_TIER_COUNT #undef X_TIER_COUNT
@ -255,4 +269,35 @@ void stream::Stream<LimitsForCompilationRequest>::Write(Sink* s,
t.VisitAll([&](const auto&... members) { StreamIn(s, members...); }); t.VisitAll([&](const auto&... members) { StreamIn(s, members...); });
} }
void NormalizeLimits(Limits* limits) {
// Enforce internal Dawn constants for some limits to ensure they don't go over fixed-size
// arrays in Dawn's internal code.
limits->maxVertexBufferArrayStride =
std::min(limits->maxVertexBufferArrayStride, kMaxVertexBufferArrayStride);
limits->maxColorAttachments =
std::min(limits->maxColorAttachments, uint32_t(kMaxColorAttachments));
limits->maxBindGroups = std::min(limits->maxBindGroups, kMaxBindGroups);
limits->maxVertexAttributes =
std::min(limits->maxVertexAttributes, uint32_t(kMaxVertexAttributes));
limits->maxVertexBuffers = std::min(limits->maxVertexBuffers, uint32_t(kMaxVertexBuffers));
limits->maxInterStageShaderComponents =
std::min(limits->maxInterStageShaderComponents, kMaxInterStageShaderComponents);
limits->maxSampledTexturesPerShaderStage =
std::min(limits->maxSampledTexturesPerShaderStage, kMaxSampledTexturesPerShaderStage);
limits->maxSamplersPerShaderStage =
std::min(limits->maxSamplersPerShaderStage, kMaxSamplersPerShaderStage);
limits->maxStorageBuffersPerShaderStage =
std::min(limits->maxStorageBuffersPerShaderStage, kMaxStorageBuffersPerShaderStage);
limits->maxStorageTexturesPerShaderStage =
std::min(limits->maxStorageTexturesPerShaderStage, kMaxStorageTexturesPerShaderStage);
limits->maxUniformBuffersPerShaderStage =
std::min(limits->maxUniformBuffersPerShaderStage, kMaxUniformBuffersPerShaderStage);
// Additional enforcement for dependent limits.
limits->maxStorageBufferBindingSize =
std::min(limits->maxStorageBufferBindingSize, limits->maxBufferSize);
limits->maxUniformBufferBindingSize =
std::min(limits->maxUniformBufferBindingSize, limits->maxBufferSize);
}
} // namespace dawn::native } // namespace dawn::native

View File

@ -53,6 +53,13 @@ struct LimitsForCompilationRequest {
DAWN_VISITABLE_MEMBERS(LIMITS_FOR_COMPILATION_REQUEST_MEMBERS) DAWN_VISITABLE_MEMBERS(LIMITS_FOR_COMPILATION_REQUEST_MEMBERS)
}; };
// Enforce restriction for limit values, including:
// 1. Enforce internal Dawn constants for some limits to ensure they don't go over fixed-size
// arrays in Dawn's internal code;
// 2. Additional enforcement for dependent limits, e.g. maxStorageBufferBindingSize and
// maxUniformBufferBindingSize must not be larger than maxBufferSize.
void NormalizeLimits(Limits* limits);
} // namespace dawn::native } // namespace dawn::native
#endif // SRC_DAWN_NATIVE_LIMITS_H_ #endif // SRC_DAWN_NATIVE_LIMITS_H_

View File

@ -51,35 +51,7 @@ MaybeError PhysicalDeviceBase::Initialize() {
"backend=%s type=%s)", "backend=%s type=%s)",
mName, mDriverDescription, mVendorId, mDeviceId, mBackend, mAdapterType); mName, mDriverDescription, mVendorId, mDeviceId, mBackend, mAdapterType);
// Enforce internal Dawn constants for some limits to ensure they don't go over fixed-size NormalizeLimits(&mLimits.v1);
// arrays in Dawn's internal code.
mLimits.v1.maxVertexBufferArrayStride =
std::min(mLimits.v1.maxVertexBufferArrayStride, kMaxVertexBufferArrayStride);
mLimits.v1.maxColorAttachments =
std::min(mLimits.v1.maxColorAttachments, uint32_t(kMaxColorAttachments));
mLimits.v1.maxBindGroups = std::min(mLimits.v1.maxBindGroups, kMaxBindGroups);
mLimits.v1.maxVertexAttributes =
std::min(mLimits.v1.maxVertexAttributes, uint32_t(kMaxVertexAttributes));
mLimits.v1.maxVertexBuffers =
std::min(mLimits.v1.maxVertexBuffers, uint32_t(kMaxVertexBuffers));
mLimits.v1.maxInterStageShaderComponents =
std::min(mLimits.v1.maxInterStageShaderComponents, kMaxInterStageShaderComponents);
mLimits.v1.maxSampledTexturesPerShaderStage =
std::min(mLimits.v1.maxSampledTexturesPerShaderStage, kMaxSampledTexturesPerShaderStage);
mLimits.v1.maxSamplersPerShaderStage =
std::min(mLimits.v1.maxSamplersPerShaderStage, kMaxSamplersPerShaderStage);
mLimits.v1.maxStorageBuffersPerShaderStage =
std::min(mLimits.v1.maxStorageBuffersPerShaderStage, kMaxStorageBuffersPerShaderStage);
mLimits.v1.maxStorageTexturesPerShaderStage =
std::min(mLimits.v1.maxStorageTexturesPerShaderStage, kMaxStorageTexturesPerShaderStage);
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 {}; return {};
} }

View File

@ -14,6 +14,7 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "dawn/common/Constants.h"
#include "dawn/native/Limits.h" #include "dawn/native/Limits.h"
// Test |GetDefaultLimits| returns the default. // Test |GetDefaultLimits| returns the default.
@ -123,14 +124,22 @@ TEST(Limits, ValidateLimits) {
// Test that |ApplyLimitTiers| degrades limits to the next best tier. // Test that |ApplyLimitTiers| degrades limits to the next best tier.
TEST(Limits, ApplyLimitTiers) { TEST(Limits, ApplyLimitTiers) {
auto SetLimitsStorageBufferBindingSizeTier2 = [](dawn::native::Limits* limits) { auto SetLimitsStorageBufferBindingSizeTier2 = [](dawn::native::Limits* limits) {
// Tier 2 of maxStorageBufferBindingSize is 1GB
limits->maxStorageBufferBindingSize = 1073741824; limits->maxStorageBufferBindingSize = 1073741824;
// Also set the maxBufferSize to be large enough, as ApplyLimitTiers ensures tired
// maxStorageBufferBindingSize no larger than tiered maxBufferSize.
limits->maxBufferSize = 2147483648;
}; };
dawn::native::Limits limitsStorageBufferBindingSizeTier2; dawn::native::Limits limitsStorageBufferBindingSizeTier2;
dawn::native::GetDefaultLimits(&limitsStorageBufferBindingSizeTier2); dawn::native::GetDefaultLimits(&limitsStorageBufferBindingSizeTier2);
SetLimitsStorageBufferBindingSizeTier2(&limitsStorageBufferBindingSizeTier2); SetLimitsStorageBufferBindingSizeTier2(&limitsStorageBufferBindingSizeTier2);
auto SetLimitsStorageBufferBindingSizeTier3 = [](dawn::native::Limits* limits) { auto SetLimitsStorageBufferBindingSizeTier3 = [](dawn::native::Limits* limits) {
limits->maxStorageBufferBindingSize = 2147483647; // Tier 3 of maxStorageBufferBindingSize is 2GB-4
limits->maxStorageBufferBindingSize = 2147483644;
// Also set the maxBufferSize to be large enough, as ApplyLimitTiers ensures tired
// maxStorageBufferBindingSize no larger than tiered maxBufferSize.
limits->maxBufferSize = 2147483648;
}; };
dawn::native::Limits limitsStorageBufferBindingSizeTier3; dawn::native::Limits limitsStorageBufferBindingSizeTier3;
dawn::native::GetDefaultLimits(&limitsStorageBufferBindingSizeTier3); dawn::native::GetDefaultLimits(&limitsStorageBufferBindingSizeTier3);
@ -207,3 +216,228 @@ TEST(Limits, ApplyLimitTiers) {
EXPECT_EQ(tiered, expected); EXPECT_EQ(tiered, expected);
} }
} }
// Test that |ApplyLimitTiers| will hold the maxStorageBufferBindingSize no larger than
// maxBufferSize restriction.
TEST(Limits, TieredMaxStorageBufferBindingSizeNoLargerThanMaxBufferSize) {
// Start with the default for supported.
dawn::native::Limits defaults;
dawn::native::GetDefaultLimits(&defaults);
// Test reported maxStorageBufferBindingSize around 128MB, 1GB, 2GB-4 and 4GB-4.
constexpr uint64_t storageSizeTier1 = 134217728ull; // 128MB
constexpr uint64_t storageSizeTier2 = 1073741824ull; // 1GB
constexpr uint64_t storageSizeTier3 = 2147483644ull; // 2GB-4
constexpr uint64_t storageSizeTier4 = 4294967292ull; // 4GB-4
constexpr uint64_t possibleReportedMaxStorageBufferBindingSizes[] = {
storageSizeTier1, storageSizeTier1 + 1, storageSizeTier2 - 1, storageSizeTier2,
storageSizeTier2 + 1, storageSizeTier3 - 1, storageSizeTier3, storageSizeTier3 + 1,
storageSizeTier4 - 1, storageSizeTier4, storageSizeTier4 + 1};
// Test reported maxBufferSize around 256MB, 1GB, 2GB and 4GB, and a large 256GB.
constexpr uint64_t bufferSizeTier1 = 0x10000000ull; // 256MB
constexpr uint64_t bufferSizeTier2 = 0x40000000ull; // 1GB
constexpr uint64_t bufferSizeTier3 = 0x80000000ull; // 2GB
constexpr uint64_t bufferSizeTier4 = 0x100000000ull; // 4GB
constexpr uint64_t bufferSizeLarge = 0x4000000000ull; // 256GB
constexpr uint64_t possibleReportedMaxBufferSizes[] = {
bufferSizeTier1, bufferSizeTier1 + 1, bufferSizeTier2 - 1, bufferSizeTier2,
bufferSizeTier2 + 1, bufferSizeTier3 - 1, bufferSizeTier3, bufferSizeTier3 + 1,
bufferSizeTier4 - 1, bufferSizeTier4, bufferSizeTier4 + 1, bufferSizeLarge};
// Test that tiered maxStorageBufferBindingSize is no larger than tiered maxBufferSize.
for (uint64_t reportedMaxStorageBufferBindingSizes :
possibleReportedMaxStorageBufferBindingSizes) {
for (uint64_t reportedMaxBufferSizes : possibleReportedMaxBufferSizes) {
dawn::native::Limits limits = defaults;
limits.maxStorageBufferBindingSize = reportedMaxStorageBufferBindingSizes;
limits.maxBufferSize = reportedMaxBufferSizes;
dawn::native::Limits tiered = ApplyLimitTiers(limits);
EXPECT_LE(tiered.maxStorageBufferBindingSize, tiered.maxBufferSize);
}
}
}
// Test that |ApplyLimitTiers| will hold the maxUniformBufferBindingSize no larger than
// maxBufferSize restriction.
TEST(Limits, TieredMaxUniformBufferBindingSizeNoLargerThanMaxBufferSize) {
// Start with the default for supported.
dawn::native::Limits defaults;
dawn::native::GetDefaultLimits(&defaults);
// Test reported maxStorageBufferBindingSize around 64KB, and a large 1GB.
constexpr uint64_t uniformSizeTier1 = 65536ull; // 64KB
constexpr uint64_t uniformSizeLarge = 1073741824ull; // 1GB
constexpr uint64_t possibleReportedMaxUniformBufferBindingSizes[] = {
uniformSizeTier1, uniformSizeTier1 + 1, uniformSizeLarge};
// Test reported maxBufferSize around 256MB, 1GB, 2GB and 4GB, and a large 256GB.
constexpr uint64_t bufferSizeTier1 = 0x10000000ull; // 256MB
constexpr uint64_t bufferSizeTier2 = 0x40000000ull; // 1GB
constexpr uint64_t bufferSizeTier3 = 0x80000000ull; // 2GB
constexpr uint64_t bufferSizeTier4 = 0x100000000ull; // 4GB
constexpr uint64_t bufferSizeLarge = 0x4000000000ull; // 256GB
constexpr uint64_t possibleReportedMaxBufferSizes[] = {
bufferSizeTier1, bufferSizeTier1 + 1, bufferSizeTier2 - 1, bufferSizeTier2,
bufferSizeTier2 + 1, bufferSizeTier3 - 1, bufferSizeTier3, bufferSizeTier3 + 1,
bufferSizeTier4 - 1, bufferSizeTier4, bufferSizeTier4 + 1, bufferSizeLarge};
// Test that tiered maxUniformBufferBindingSize is no larger than tiered maxBufferSize.
for (uint64_t reportedMaxUniformBufferBindingSizes :
possibleReportedMaxUniformBufferBindingSizes) {
for (uint64_t reportedMaxBufferSizes : possibleReportedMaxBufferSizes) {
dawn::native::Limits limits = defaults;
limits.maxUniformBufferBindingSize = reportedMaxUniformBufferBindingSizes;
limits.maxBufferSize = reportedMaxBufferSizes;
dawn::native::Limits tiered = ApplyLimitTiers(limits);
EXPECT_LE(tiered.maxUniformBufferBindingSize, tiered.maxBufferSize);
}
}
}
// Test |NormalizeLimits| works to enforce restriction of limits.
TEST(Limits, NormalizeLimits) {
// Start with the default for supported.
dawn::native::Limits defaults;
dawn::native::GetDefaultLimits(&defaults);
// Test specific limit values are clamped to internal Dawn constants.
{
dawn::native::Limits limits = defaults;
limits.maxVertexBufferArrayStride = kMaxVertexBufferArrayStride + 1;
limits.maxColorAttachments = uint32_t(kMaxColorAttachments) + 1;
limits.maxBindGroups = kMaxBindGroups + 1;
limits.maxVertexAttributes = uint32_t(kMaxVertexAttributes) + 1;
limits.maxVertexBuffers = uint32_t(kMaxVertexBuffers) + 1;
limits.maxInterStageShaderComponents = kMaxInterStageShaderComponents + 1;
limits.maxSampledTexturesPerShaderStage = kMaxSampledTexturesPerShaderStage + 1;
limits.maxSamplersPerShaderStage = kMaxSamplersPerShaderStage + 1;
limits.maxStorageBuffersPerShaderStage = kMaxStorageBuffersPerShaderStage + 1;
limits.maxStorageTexturesPerShaderStage = kMaxStorageTexturesPerShaderStage + 1;
limits.maxUniformBuffersPerShaderStage = kMaxUniformBuffersPerShaderStage + 1;
NormalizeLimits(&limits);
EXPECT_EQ(limits.maxVertexBufferArrayStride, kMaxVertexBufferArrayStride);
EXPECT_EQ(limits.maxColorAttachments, uint32_t(kMaxColorAttachments));
EXPECT_EQ(limits.maxBindGroups, kMaxBindGroups);
EXPECT_EQ(limits.maxVertexAttributes, uint32_t(kMaxVertexAttributes));
EXPECT_EQ(limits.maxVertexBuffers, uint32_t(kMaxVertexBuffers));
EXPECT_EQ(limits.maxInterStageShaderComponents, kMaxInterStageShaderComponents);
EXPECT_EQ(limits.maxSampledTexturesPerShaderStage, kMaxSampledTexturesPerShaderStage);
EXPECT_EQ(limits.maxSamplersPerShaderStage, kMaxSamplersPerShaderStage);
EXPECT_EQ(limits.maxStorageBuffersPerShaderStage, kMaxStorageBuffersPerShaderStage);
EXPECT_EQ(limits.maxStorageTexturesPerShaderStage, kMaxStorageTexturesPerShaderStage);
EXPECT_EQ(limits.maxUniformBuffersPerShaderStage, kMaxUniformBuffersPerShaderStage);
}
// Test maxStorageBufferBindingSize is clamped to maxBufferSize.
// maxStorageBufferBindingSize is no larger than maxBufferSize
{
constexpr uint64_t reportedMaxBufferSize = 2147483648;
constexpr uint64_t reportedMaxStorageBufferBindingSize = reportedMaxBufferSize;
dawn::native::Limits limits = defaults;
limits.maxStorageBufferBindingSize = reportedMaxStorageBufferBindingSize;
limits.maxBufferSize = reportedMaxBufferSize;
NormalizeLimits(&limits);
EXPECT_EQ(limits.maxBufferSize, reportedMaxBufferSize);
EXPECT_EQ(limits.maxStorageBufferBindingSize, reportedMaxStorageBufferBindingSize);
}
{
constexpr uint64_t reportedMaxBufferSize = 2147483648;
constexpr uint64_t reportedMaxStorageBufferBindingSize = reportedMaxBufferSize - 1;
dawn::native::Limits limits = defaults;
limits.maxStorageBufferBindingSize = reportedMaxStorageBufferBindingSize;
limits.maxBufferSize = reportedMaxBufferSize;
NormalizeLimits(&limits);
EXPECT_EQ(limits.maxBufferSize, reportedMaxBufferSize);
EXPECT_EQ(limits.maxStorageBufferBindingSize, reportedMaxStorageBufferBindingSize);
}
// maxStorageBufferBindingSize is equal to maxBufferSize+1, expect clamping to maxBufferSize
{
constexpr uint64_t reportedMaxBufferSize = 2147483648;
constexpr uint64_t reportedMaxStorageBufferBindingSize = reportedMaxBufferSize + 1;
dawn::native::Limits limits = defaults;
limits.maxStorageBufferBindingSize = reportedMaxStorageBufferBindingSize;
limits.maxBufferSize = reportedMaxBufferSize;
NormalizeLimits(&limits);
EXPECT_EQ(limits.maxBufferSize, reportedMaxBufferSize);
EXPECT_EQ(limits.maxStorageBufferBindingSize, reportedMaxBufferSize);
}
// maxStorageBufferBindingSize is much larger than maxBufferSize, expect clamping to
// maxBufferSize
{
constexpr uint64_t reportedMaxBufferSize = 2147483648;
constexpr uint64_t reportedMaxStorageBufferBindingSize = 4294967295;
dawn::native::Limits limits = defaults;
limits.maxStorageBufferBindingSize = reportedMaxStorageBufferBindingSize;
limits.maxBufferSize = reportedMaxBufferSize;
NormalizeLimits(&limits);
EXPECT_EQ(limits.maxBufferSize, reportedMaxBufferSize);
EXPECT_EQ(limits.maxStorageBufferBindingSize, reportedMaxBufferSize);
}
// Test maxUniformBufferBindingSize is clamped to maxBufferSize.
// maxUniformBufferBindingSize is no larger than maxBufferSize
{
constexpr uint64_t reportedMaxBufferSize = 2147483648;
constexpr uint64_t reportedMaxUniformBufferBindingSize = reportedMaxBufferSize - 1;
dawn::native::Limits limits = defaults;
limits.maxUniformBufferBindingSize = reportedMaxUniformBufferBindingSize;
limits.maxBufferSize = reportedMaxBufferSize;
NormalizeLimits(&limits);
EXPECT_EQ(limits.maxBufferSize, reportedMaxBufferSize);
EXPECT_EQ(limits.maxUniformBufferBindingSize, reportedMaxUniformBufferBindingSize);
}
{
constexpr uint64_t reportedMaxBufferSize = 2147483648;
constexpr uint64_t reportedMaxUniformBufferBindingSize = reportedMaxBufferSize;
dawn::native::Limits limits = defaults;
limits.maxUniformBufferBindingSize = reportedMaxUniformBufferBindingSize;
limits.maxBufferSize = reportedMaxBufferSize;
NormalizeLimits(&limits);
EXPECT_EQ(limits.maxBufferSize, reportedMaxBufferSize);
EXPECT_EQ(limits.maxUniformBufferBindingSize, reportedMaxUniformBufferBindingSize);
}
// maxUniformBufferBindingSize is larger than maxBufferSize, expect clamping to maxBufferSize
{
constexpr uint64_t reportedMaxBufferSize = 2147483648;
constexpr uint64_t reportedMaxUniformBufferBindingSize = reportedMaxBufferSize + 1;
dawn::native::Limits limits = defaults;
limits.maxUniformBufferBindingSize = reportedMaxUniformBufferBindingSize;
limits.maxBufferSize = reportedMaxBufferSize;
NormalizeLimits(&limits);
EXPECT_EQ(limits.maxBufferSize, reportedMaxBufferSize);
EXPECT_EQ(limits.maxUniformBufferBindingSize, reportedMaxBufferSize);
}
// maxUniformBufferBindingSize is much larger than maxBufferSize, expect clamping to
// maxBufferSize
{
constexpr uint64_t reportedMaxBufferSize = 2147483648;
constexpr uint64_t reportedMaxUniformBufferBindingSize = 4294967295;
dawn::native::Limits limits = defaults;
limits.maxUniformBufferBindingSize = reportedMaxUniformBufferBindingSize;
limits.maxBufferSize = reportedMaxBufferSize;
NormalizeLimits(&limits);
EXPECT_EQ(limits.maxBufferSize, reportedMaxBufferSize);
EXPECT_EQ(limits.maxUniformBufferBindingSize, reportedMaxBufferSize);
}
}