Add maxColorAttachments limit
Bug: dawn:1455 Change-Id: I92ceb62df46cfb54a791d53a72921e99f46bca08 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/93307 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Shrek Shao <shrekshao@google.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
06cc5c1acd
commit
cda3d7bfa8
|
@ -1263,6 +1263,7 @@
|
||||||
{"name": "max vertex attributes", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
{"name": "max vertex attributes", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||||
{"name": "max vertex buffer array stride", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
{"name": "max vertex buffer array stride", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||||
{"name": "max inter stage shader components", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
{"name": "max inter stage shader components", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||||
|
{"name": "max color attachments", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||||
{"name": "max compute workgroup storage size", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
{"name": "max compute workgroup storage size", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||||
{"name": "max compute invocations per workgroup", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
{"name": "max compute invocations per workgroup", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||||
{"name": "max compute workgroup size x", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
{"name": "max compute workgroup size x", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||||
|
|
|
@ -49,6 +49,8 @@ MaybeError AdapterBase::Initialize() {
|
||||||
// Enforce internal Dawn constants.
|
// Enforce internal Dawn constants.
|
||||||
mLimits.v1.maxVertexBufferArrayStride =
|
mLimits.v1.maxVertexBufferArrayStride =
|
||||||
std::min(mLimits.v1.maxVertexBufferArrayStride, kMaxVertexBufferArrayStride);
|
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.maxBindGroups = std::min(mLimits.v1.maxBindGroups, kMaxBindGroups);
|
||||||
mLimits.v1.maxVertexAttributes =
|
mLimits.v1.maxVertexAttributes =
|
||||||
std::min(mLimits.v1.maxVertexAttributes, uint32_t(kMaxVertexAttributes));
|
std::min(mLimits.v1.maxVertexAttributes, uint32_t(kMaxVertexAttributes));
|
||||||
|
|
|
@ -445,10 +445,11 @@ MaybeError ValidateRenderPassDescriptor(DeviceBase* device,
|
||||||
uint32_t* height,
|
uint32_t* height,
|
||||||
uint32_t* sampleCount,
|
uint32_t* sampleCount,
|
||||||
UsageValidationMode usageValidationMode) {
|
UsageValidationMode usageValidationMode) {
|
||||||
|
uint32_t maxColorAttachments = device->GetLimits().v1.maxColorAttachments;
|
||||||
DAWN_INVALID_IF(
|
DAWN_INVALID_IF(
|
||||||
descriptor->colorAttachmentCount > kMaxColorAttachments,
|
descriptor->colorAttachmentCount > maxColorAttachments,
|
||||||
"Color attachment count (%u) exceeds the maximum number of color attachments (%u).",
|
"Color attachment count (%u) exceeds the maximum number of color attachments (%u).",
|
||||||
descriptor->colorAttachmentCount, kMaxColorAttachments);
|
descriptor->colorAttachmentCount, maxColorAttachments);
|
||||||
|
|
||||||
bool isAllColorAttachmentNull = true;
|
bool isAllColorAttachmentNull = true;
|
||||||
for (uint32_t i = 0; i < descriptor->colorAttachmentCount; ++i) {
|
for (uint32_t i = 0; i < descriptor->colorAttachmentCount; ++i) {
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
X(Maximum, maxVertexAttributes, 16, 16) \
|
X(Maximum, maxVertexAttributes, 16, 16) \
|
||||||
X(Maximum, maxVertexBufferArrayStride, 2048, 2048) \
|
X(Maximum, maxVertexBufferArrayStride, 2048, 2048) \
|
||||||
X(Maximum, maxInterStageShaderComponents, 60, 60) \
|
X(Maximum, maxInterStageShaderComponents, 60, 60) \
|
||||||
|
X(Maximum, maxColorAttachments, 8, 8) \
|
||||||
X(Maximum, maxComputeInvocationsPerWorkgroup, 256, 256) \
|
X(Maximum, maxComputeInvocationsPerWorkgroup, 256, 256) \
|
||||||
X(Maximum, maxComputeWorkgroupSizeX, 256, 256) \
|
X(Maximum, maxComputeWorkgroupSizeX, 256, 256) \
|
||||||
X(Maximum, maxComputeWorkgroupSizeY, 256, 256) \
|
X(Maximum, maxComputeWorkgroupSizeY, 256, 256) \
|
||||||
|
|
|
@ -62,9 +62,10 @@ MaybeError ValidateRenderBundleEncoderDescriptor(const DeviceBase* device,
|
||||||
DAWN_INVALID_IF(!IsValidSampleCount(descriptor->sampleCount),
|
DAWN_INVALID_IF(!IsValidSampleCount(descriptor->sampleCount),
|
||||||
"Sample count (%u) is not supported.", descriptor->sampleCount);
|
"Sample count (%u) is not supported.", descriptor->sampleCount);
|
||||||
|
|
||||||
DAWN_INVALID_IF(descriptor->colorFormatsCount > kMaxColorAttachments,
|
uint32_t maxColorAttachments = device->GetLimits().v1.maxColorAttachments;
|
||||||
|
DAWN_INVALID_IF(descriptor->colorFormatsCount > maxColorAttachments,
|
||||||
"Color formats count (%u) exceeds maximum number of color attachements (%u).",
|
"Color formats count (%u) exceeds maximum number of color attachements (%u).",
|
||||||
descriptor->colorFormatsCount, kMaxColorAttachments);
|
descriptor->colorFormatsCount, maxColorAttachments);
|
||||||
|
|
||||||
bool allColorFormatsUndefined = true;
|
bool allColorFormatsUndefined = true;
|
||||||
for (uint32_t i = 0; i < descriptor->colorFormatsCount; ++i) {
|
for (uint32_t i = 0; i < descriptor->colorFormatsCount; ++i) {
|
||||||
|
|
|
@ -330,9 +330,10 @@ MaybeError ValidateFragmentState(DeviceBase* device,
|
||||||
"validating fragment stage (module: %s, entryPoint: %s).", descriptor->module,
|
"validating fragment stage (module: %s, entryPoint: %s).", descriptor->module,
|
||||||
descriptor->entryPoint);
|
descriptor->entryPoint);
|
||||||
|
|
||||||
DAWN_INVALID_IF(descriptor->targetCount > kMaxColorAttachments,
|
uint32_t maxColorAttachments = device->GetLimits().v1.maxColorAttachments;
|
||||||
|
DAWN_INVALID_IF(descriptor->targetCount > maxColorAttachments,
|
||||||
"Number of targets (%u) exceeds the maximum (%u).", descriptor->targetCount,
|
"Number of targets (%u) exceeds the maximum (%u).", descriptor->targetCount,
|
||||||
kMaxColorAttachments);
|
maxColorAttachments);
|
||||||
|
|
||||||
const EntryPointMetadata& fragmentMetadata =
|
const EntryPointMetadata& fragmentMetadata =
|
||||||
descriptor->module->GetEntryPoint(descriptor->entryPoint);
|
descriptor->module->GetEntryPoint(descriptor->entryPoint);
|
||||||
|
|
|
@ -784,6 +784,7 @@ ResultOrError<std::unique_ptr<EntryPointMetadata>> ReflectEntryPointUsingTint(
|
||||||
"Total fragment input components count (%u) exceeds the maximum (%u).",
|
"Total fragment input components count (%u) exceeds the maximum (%u).",
|
||||||
totalInterStageShaderComponents, kMaxInterStageShaderComponents);
|
totalInterStageShaderComponents, kMaxInterStageShaderComponents);
|
||||||
|
|
||||||
|
uint32_t maxColorAttachments = device->GetLimits().v1.maxColorAttachments;
|
||||||
for (const auto& outputVar : entryPoint.output_variables) {
|
for (const auto& outputVar : entryPoint.output_variables) {
|
||||||
EntryPointMetadata::FragmentOutputVariableInfo variable;
|
EntryPointMetadata::FragmentOutputVariableInfo variable;
|
||||||
DAWN_TRY_ASSIGN(variable.baseType,
|
DAWN_TRY_ASSIGN(variable.baseType,
|
||||||
|
@ -793,10 +794,10 @@ ResultOrError<std::unique_ptr<EntryPointMetadata>> ReflectEntryPointUsingTint(
|
||||||
ASSERT(variable.componentCount <= 4);
|
ASSERT(variable.componentCount <= 4);
|
||||||
|
|
||||||
uint32_t unsanitizedAttachment = outputVar.location_decoration;
|
uint32_t unsanitizedAttachment = outputVar.location_decoration;
|
||||||
if (DelayedInvalidIf(unsanitizedAttachment >= kMaxColorAttachments,
|
if (DelayedInvalidIf(unsanitizedAttachment >= maxColorAttachments,
|
||||||
"Fragment output variable \"%s\" has a location (%u) that "
|
"Fragment output variable \"%s\" has a location (%u) that "
|
||||||
"exceeds the maximum (%u).",
|
"exceeds the maximum (%u).",
|
||||||
outputVar.name, unsanitizedAttachment, kMaxColorAttachments)) {
|
outputVar.name, unsanitizedAttachment, maxColorAttachments)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -241,6 +241,8 @@ MaybeError Adapter::InitializeSupportedLimitsImpl(CombinedLimits* limits) {
|
||||||
limits->v1.maxSampledTexturesPerShaderStage = maxSRVsPerStage;
|
limits->v1.maxSampledTexturesPerShaderStage = maxSRVsPerStage;
|
||||||
limits->v1.maxSamplersPerShaderStage = maxSamplersPerStage;
|
limits->v1.maxSamplersPerShaderStage = maxSamplersPerStage;
|
||||||
|
|
||||||
|
limits->v1.maxColorAttachments = D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT;
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/direct3d12/root-signature-limits
|
// https://docs.microsoft.com/en-us/windows/win32/direct3d12/root-signature-limits
|
||||||
// In DWORDS. Descriptor tables cost 1, Root constants cost 1, Root descriptors cost 2.
|
// In DWORDS. Descriptor tables cost 1, Root constants cost 1, Root descriptors cost 2.
|
||||||
static constexpr uint32_t kMaxRootSignatureSize = 64u;
|
static constexpr uint32_t kMaxRootSignatureSize = 64u;
|
||||||
|
|
|
@ -518,6 +518,7 @@ class Adapter : public AdapterBase {
|
||||||
uint32_t max3DTextureSize;
|
uint32_t max3DTextureSize;
|
||||||
uint32_t maxTextureArrayLayers;
|
uint32_t maxTextureArrayLayers;
|
||||||
uint32_t minBufferOffsetAlignment;
|
uint32_t minBufferOffsetAlignment;
|
||||||
|
uint32_t maxColorRenderTargets;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LimitsForFamily {
|
struct LimitsForFamily {
|
||||||
|
@ -529,7 +530,7 @@ class Adapter : public AdapterBase {
|
||||||
// https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
|
// https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
|
||||||
// Apple Mac
|
// Apple Mac
|
||||||
// 1, 2, 3, 4, 5, 6, 7, 1, 2
|
// 1, 2, 3, 4, 5, 6, 7, 1, 2
|
||||||
constexpr LimitsForFamily kMTLLimits[12] = {
|
constexpr LimitsForFamily kMTLLimits[13] = {
|
||||||
{&MTLDeviceLimits::maxVertexAttribsPerDescriptor, { 31u, 31u, 31u, 31u, 31u, 31u, 31u, 31u, 31u }},
|
{&MTLDeviceLimits::maxVertexAttribsPerDescriptor, { 31u, 31u, 31u, 31u, 31u, 31u, 31u, 31u, 31u }},
|
||||||
{&MTLDeviceLimits::maxBufferArgumentEntriesPerFunc, { 31u, 31u, 31u, 31u, 31u, 31u, 31u, 31u, 31u }},
|
{&MTLDeviceLimits::maxBufferArgumentEntriesPerFunc, { 31u, 31u, 31u, 31u, 31u, 31u, 31u, 31u, 31u }},
|
||||||
{&MTLDeviceLimits::maxTextureArgumentEntriesPerFunc, { 31u, 31u, 31u, 96u, 96u, 128u, 128u, 128u, 128u }},
|
{&MTLDeviceLimits::maxTextureArgumentEntriesPerFunc, { 31u, 31u, 31u, 96u, 96u, 128u, 128u, 128u, 128u }},
|
||||||
|
@ -542,6 +543,7 @@ class Adapter : public AdapterBase {
|
||||||
{&MTLDeviceLimits::max3DTextureSize, { 2048u, 2048u, 2048u, 2048u, 2048u, 2048u, 2048u, 2048u, 2048u }},
|
{&MTLDeviceLimits::max3DTextureSize, { 2048u, 2048u, 2048u, 2048u, 2048u, 2048u, 2048u, 2048u, 2048u }},
|
||||||
{&MTLDeviceLimits::maxTextureArrayLayers, { 2048u, 2048u, 2048u, 2048u, 2048u, 2048u, 2048u, 2048u, 2048u }},
|
{&MTLDeviceLimits::maxTextureArrayLayers, { 2048u, 2048u, 2048u, 2048u, 2048u, 2048u, 2048u, 2048u, 2048u }},
|
||||||
{&MTLDeviceLimits::minBufferOffsetAlignment, { 4u, 4u, 4u, 4u, 4u, 4u, 4u, 256u, 256u }},
|
{&MTLDeviceLimits::minBufferOffsetAlignment, { 4u, 4u, 4u, 4u, 4u, 4u, 4u, 256u, 256u }},
|
||||||
|
{&MTLDeviceLimits::maxColorRenderTargets, { 4u, 8u, 8u, 8u, 8u, 8u, 8u, 8u, 8u }},
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
@ -559,6 +561,7 @@ class Adapter : public AdapterBase {
|
||||||
limits->v1.maxTextureDimension2D = mtlLimits.max2DTextureSize;
|
limits->v1.maxTextureDimension2D = mtlLimits.max2DTextureSize;
|
||||||
limits->v1.maxTextureDimension3D = mtlLimits.max3DTextureSize;
|
limits->v1.maxTextureDimension3D = mtlLimits.max3DTextureSize;
|
||||||
limits->v1.maxTextureArrayLayers = mtlLimits.maxTextureArrayLayers;
|
limits->v1.maxTextureArrayLayers = mtlLimits.maxTextureArrayLayers;
|
||||||
|
limits->v1.maxColorAttachments = mtlLimits.maxColorRenderTargets;
|
||||||
|
|
||||||
uint32_t maxBuffersPerStage = mtlLimits.maxBufferArgumentEntriesPerFunc;
|
uint32_t maxBuffersPerStage = mtlLimits.maxBufferArgumentEntriesPerFunc;
|
||||||
maxBuffersPerStage -= 1; // One slot is reserved to store buffer lengths.
|
maxBuffersPerStage -= 1; // One slot is reserved to store buffer lengths.
|
||||||
|
@ -624,7 +627,7 @@ class Adapter : public AdapterBase {
|
||||||
limits->v1.maxStorageBufferBindingSize = maxBufferSize;
|
limits->v1.maxStorageBufferBindingSize = maxBufferSize;
|
||||||
|
|
||||||
// TODO(crbug.com/dawn/685):
|
// TODO(crbug.com/dawn/685):
|
||||||
// LIMITS NOT SET:
|
// Using base limits for:
|
||||||
// - maxBindGroups
|
// - maxBindGroups
|
||||||
// - maxVertexBufferArrayStride
|
// - maxVertexBufferArrayStride
|
||||||
|
|
||||||
|
|
|
@ -281,9 +281,7 @@ MaybeError Adapter::InitializeSupportedLimitsImpl(CombinedLimits* limits) {
|
||||||
vkLimits.maxComputeWorkGroupCount[2],
|
vkLimits.maxComputeWorkGroupCount[2],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (vkLimits.maxColorAttachments < kMaxColorAttachments) {
|
CHECK_AND_SET_V1_MAX_LIMIT(maxColorAttachments, maxColorAttachments);
|
||||||
return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxColorAttachments");
|
|
||||||
}
|
|
||||||
if (!IsSubset(VkSampleCountFlags(VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT),
|
if (!IsSubset(VkSampleCountFlags(VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT),
|
||||||
vkLimits.framebufferColorSampleCounts)) {
|
vkLimits.framebufferColorSampleCounts)) {
|
||||||
return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for framebufferColorSampleCounts");
|
return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for framebufferColorSampleCounts");
|
||||||
|
|
Loading…
Reference in New Issue