Skip to content

Commit 525d231

Browse files
crowlKatsbartlomieju
authored andcommitted
fix(ext/webgpu): normalize limits to number (#27072)
Fixes #22029
1 parent f34e76a commit 525d231

File tree

2 files changed

+103
-30
lines changed

2 files changed

+103
-30
lines changed

ext/webgpu/01_webgpu.js

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ const {
9898
ArrayPrototypePush,
9999
DataViewPrototypeGetBuffer,
100100
Error,
101+
Number,
102+
NumberPOSITIVE_INFINITY,
103+
NumberMAX_SAFE_INTEGER,
104+
NumberNEGATIVE_INFINITY,
105+
NumberMIN_SAFE_INTEGER,
101106
MathMax,
102107
ObjectDefineProperty,
103108
ObjectHasOwn,
@@ -614,6 +619,19 @@ function createGPUSupportedLimits(limits) {
614619
return adapterFeatures;
615620
}
616621

622+
function normalizeLimit(limit) {
623+
if (typeof num === "bigint") {
624+
limit = Number(limit);
625+
if (limit === NumberPOSITIVE_INFINITY) {
626+
limit = NumberMAX_SAFE_INTEGER;
627+
} else if (limit === NumberNEGATIVE_INFINITY) {
628+
limit = NumberMIN_SAFE_INTEGER;
629+
}
630+
}
631+
632+
return limit;
633+
}
634+
617635
/**
618636
* @typedef InnerAdapterLimits
619637
* @property {number} maxTextureDimension1D
@@ -653,123 +671,127 @@ class GPUSupportedLimits {
653671

654672
get maxTextureDimension1D() {
655673
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
656-
return this[_limits].maxTextureDimension1D;
674+
return normalizeLimit(this[_limits].maxTextureDimension1D);
657675
}
658676
get maxTextureDimension2D() {
659677
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
660-
return this[_limits].maxTextureDimension2D;
678+
return normalizeLimit(this[_limits].maxTextureDimension2D);
661679
}
662680
get maxTextureDimension3D() {
663681
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
664-
return this[_limits].maxTextureDimension3D;
682+
return normalizeLimit(this[_limits].maxTextureDimension3D);
665683
}
666684
get maxTextureArrayLayers() {
667685
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
668-
return this[_limits].maxTextureArrayLayers;
686+
return normalizeLimit(this[_limits].maxTextureArrayLayers);
669687
}
670688
get maxBindGroups() {
671689
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
672-
return this[_limits].maxBindGroups;
690+
return normalizeLimit(this[_limits].maxBindGroups);
673691
}
674692
get maxBindingsPerBindGroup() {
675693
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
676-
return this[_limits].maxBindingsPerBindGroup;
694+
return normalizeLimit(this[_limits].maxBindingsPerBindGroup);
677695
}
678696
get maxBufferSize() {
679697
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
680-
return this[_limits].maxBufferSize;
698+
return normalizeLimit(this[_limits].maxBufferSize);
681699
}
682700
get maxDynamicUniformBuffersPerPipelineLayout() {
683701
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
684-
return this[_limits].maxDynamicUniformBuffersPerPipelineLayout;
702+
return normalizeLimit(
703+
this[_limits].maxDynamicUniformBuffersPerPipelineLayout,
704+
);
685705
}
686706
get maxDynamicStorageBuffersPerPipelineLayout() {
687707
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
688-
return this[_limits].maxDynamicStorageBuffersPerPipelineLayout;
708+
return normalizeLimit(
709+
this[_limits].maxDynamicStorageBuffersPerPipelineLayout,
710+
);
689711
}
690712
get maxSampledTexturesPerShaderStage() {
691713
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
692-
return this[_limits].maxSampledTexturesPerShaderStage;
714+
return normalizeLimit(this[_limits].maxSampledTexturesPerShaderStage);
693715
}
694716
get maxSamplersPerShaderStage() {
695717
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
696-
return this[_limits].maxSamplersPerShaderStage;
718+
return normalizeLimit(this[_limits].maxSamplersPerShaderStage);
697719
}
698720
get maxStorageBuffersPerShaderStage() {
699721
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
700-
return this[_limits].maxStorageBuffersPerShaderStage;
722+
return normalizeLimit(this[_limits].maxStorageBuffersPerShaderStage);
701723
}
702724
get maxStorageTexturesPerShaderStage() {
703725
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
704-
return this[_limits].maxStorageTexturesPerShaderStage;
726+
return normalizeLimit(this[_limits].maxStorageTexturesPerShaderStage);
705727
}
706728
get maxUniformBuffersPerShaderStage() {
707729
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
708-
return this[_limits].maxUniformBuffersPerShaderStage;
730+
return normalizeLimit(this[_limits].maxUniformBuffersPerShaderStage);
709731
}
710732
get maxUniformBufferBindingSize() {
711733
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
712-
return this[_limits].maxUniformBufferBindingSize;
734+
return normalizeLimit(this[_limits].maxUniformBufferBindingSize);
713735
}
714736
get maxStorageBufferBindingSize() {
715737
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
716-
return this[_limits].maxStorageBufferBindingSize;
738+
return normalizeLimit(this[_limits].maxStorageBufferBindingSize);
717739
}
718740
get minUniformBufferOffsetAlignment() {
719741
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
720-
return this[_limits].minUniformBufferOffsetAlignment;
742+
return normalizeLimit(this[_limits].minUniformBufferOffsetAlignment);
721743
}
722744
get minStorageBufferOffsetAlignment() {
723745
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
724-
return this[_limits].minStorageBufferOffsetAlignment;
746+
return normalizeLimit(this[_limits].minStorageBufferOffsetAlignment);
725747
}
726748
get maxVertexBuffers() {
727749
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
728-
return this[_limits].maxVertexBuffers;
750+
return normalizeLimit(this[_limits].maxVertexBuffers);
729751
}
730752
get maxVertexAttributes() {
731753
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
732-
return this[_limits].maxVertexAttributes;
754+
return normalizeLimit(this[_limits].maxVertexAttributes);
733755
}
734756
get maxVertexBufferArrayStride() {
735757
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
736-
return this[_limits].maxVertexBufferArrayStride;
758+
return normalizeLimit(this[_limits].maxVertexBufferArrayStride);
737759
}
738760
get maxInterStageShaderComponents() {
739761
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
740-
return this[_limits].maxInterStageShaderComponents;
762+
return normalizeLimit(this[_limits].maxInterStageShaderComponents);
741763
}
742764
get maxColorAttachments() {
743765
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
744-
return this[_limits].maxColorAttachments;
766+
return normalizeLimit(this[_limits].maxColorAttachments);
745767
}
746768
get maxColorAttachmentBytesPerSample() {
747769
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
748-
return this[_limits].maxColorAttachmentBytesPerSample;
770+
return normalizeLimit(this[_limits].maxColorAttachmentBytesPerSample);
749771
}
750772
get maxComputeWorkgroupStorageSize() {
751773
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
752-
return this[_limits].maxComputeWorkgroupStorageSize;
774+
return normalizeLimit(this[_limits].maxComputeWorkgroupStorageSize);
753775
}
754776
get maxComputeInvocationsPerWorkgroup() {
755777
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
756-
return this[_limits].maxComputeInvocationsPerWorkgroup;
778+
return normalizeLimit(this[_limits].maxComputeInvocationsPerWorkgroup);
757779
}
758780
get maxComputeWorkgroupSizeX() {
759781
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
760-
return this[_limits].maxComputeWorkgroupSizeX;
782+
return normalizeLimit(this[_limits].maxComputeWorkgroupSizeX);
761783
}
762784
get maxComputeWorkgroupSizeY() {
763785
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
764-
return this[_limits].maxComputeWorkgroupSizeY;
786+
return normalizeLimit(this[_limits].maxComputeWorkgroupSizeY);
765787
}
766788
get maxComputeWorkgroupSizeZ() {
767789
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
768-
return this[_limits].maxComputeWorkgroupSizeZ;
790+
return normalizeLimit(this[_limits].maxComputeWorkgroupSizeZ);
769791
}
770792
get maxComputeWorkgroupsPerDimension() {
771793
webidl.assertBranded(this, GPUSupportedLimitsPrototype);
772-
return this[_limits].maxComputeWorkgroupsPerDimension;
794+
return normalizeLimit(this[_limits].maxComputeWorkgroupsPerDimension);
773795
}
774796

775797
[SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) {

tests/unit/webgpu_test.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,57 @@ Deno.test({
553553
device.destroy();
554554
});
555555

556+
Deno.test({
557+
ignore: isWsl || isCIWithoutGPU,
558+
}, async function adapterLimitsAreNumbers() {
559+
const limitNames = [
560+
"maxTextureDimension1D",
561+
"maxTextureDimension2D",
562+
"maxTextureDimension3D",
563+
"maxTextureArrayLayers",
564+
"maxBindGroups",
565+
"maxDynamicUniformBuffersPerPipelineLayout",
566+
"maxDynamicStorageBuffersPerPipelineLayout",
567+
"maxSampledTexturesPerShaderStage",
568+
"maxSamplersPerShaderStage",
569+
"maxStorageBuffersPerShaderStage",
570+
"maxStorageTexturesPerShaderStage",
571+
"maxUniformBuffersPerShaderStage",
572+
"maxUniformBufferBindingSize",
573+
"maxStorageBufferBindingSize",
574+
"minUniformBufferOffsetAlignment",
575+
"minStorageBufferOffsetAlignment",
576+
"maxVertexBuffers",
577+
"maxVertexAttributes",
578+
"maxVertexBufferArrayStride",
579+
"maxInterStageShaderComponents",
580+
"maxComputeWorkgroupStorageSize",
581+
"maxComputeInvocationsPerWorkgroup",
582+
"maxComputeWorkgroupSizeX",
583+
"maxComputeWorkgroupSizeY",
584+
"maxComputeWorkgroupSizeZ",
585+
"maxComputeWorkgroupsPerDimension",
586+
];
587+
588+
const adapter = await navigator.gpu.requestAdapter();
589+
assert(adapter);
590+
591+
for (const limitName of limitNames) {
592+
// deno-lint-ignore ban-ts-comment
593+
// @ts-ignore
594+
assertEquals(typeof adapter.limits[limitName], "number");
595+
}
596+
597+
const device = await adapter.requestDevice({
598+
// deno-lint-ignore ban-ts-comment
599+
// @ts-ignore
600+
requiredLimits: adapter.limits,
601+
});
602+
assert(device);
603+
604+
device.destroy();
605+
});
606+
556607
async function checkIsWsl() {
557608
return Deno.build.os === "linux" && await hasMicrosoftProcVersion();
558609

0 commit comments

Comments
 (0)