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:
parent
90789ea1f8
commit
960918b1b6
|
@ -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
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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 {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue