Skip to content

Commit 6105226

Browse files
Add validation tests for transient attachment usage
1 parent 3314e41 commit 6105226

File tree

4 files changed

+75
-4
lines changed

4 files changed

+75
-4
lines changed

src/webgpu/api/validation/createTexture.spec.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,10 @@ g.test('sampleCount,valid_sampleCount_with_other_parameter_varies')
343343
dimension !== '2d')) ||
344344
((usage & GPUConst.TextureUsage.STORAGE_BINDING) !== 0 &&
345345
!isTextureFormatPossiblyStorageReadable(format)) ||
346-
(mipLevelCount !== 1 && dimension === '1d')
346+
(mipLevelCount !== 1 && dimension === '1d') ||
347+
((usage & GPUConst.TextureUsage.TRANSIENT_ATTACHMENT) !== 0 &&
348+
(usage === (GPUConst.TextureUsage.RENDER_ATTACHMENT |
349+
GPUConst.TextureUsage.TRANSIENT_ATTACHMENT)))
347350
);
348351
})
349352
)
@@ -1037,6 +1040,11 @@ g.test('texture_usage')
10371040
if (isColorTextureFormat(format) && !isTextureFormatColorRenderable(t.device, format))
10381041
success = false;
10391042
}
1043+
if (usage & GPUTextureUsage.TRANSIENT_ATTACHMENT) {
1044+
if (usage !== (GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TRANSIENT_ATTACHMENT)) {
1045+
success = false;
1046+
}
1047+
}
10401048

10411049
t.expectValidationError(() => {
10421050
t.createTextureTracked(descriptor);

src/webgpu/api/validation/render_pass/render_pass_descriptor.spec.ts

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,48 @@ g.test('attachments,mip_level_count')
718718
}
719719
});
720720

721+
g.test('color_attachments,loadOp_storeOp')
722+
.desc(
723+
`
724+
Test GPURenderPassColorAttachment Usage:
725+
- if usage includes TRANSIENT_ATTACHMENT
726+
- loadOp must be clear
727+
- storeOp must be discard
728+
`
729+
)
730+
.params(u =>
731+
u
732+
.combine('format', kPossibleColorRenderableTextureFormats)
733+
.beginSubcases()
734+
.combine('transientTexture', [true, false])
735+
.combine('loadOp', ['clear', 'load'] as GPULoadOp[])
736+
.combine('storeOp', ['discard', 'store'] as GPUStoreOp[])
737+
)
738+
.fn(t => {
739+
const { format, transientTexture, loadOp, storeOp } = t.params;
740+
741+
t.skipIfTextureFormatNotSupported(format);
742+
t.skipIfTextureFormatNotUsableAsRenderAttachment(format);
743+
744+
const usage = transientTexture
745+
? GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TRANSIENT_ATTACHMENT
746+
: GPUTextureUsage.RENDER_ATTACHMENT;
747+
748+
const texture = t.createTestTexture({ usage });
749+
750+
const colorAttachment = t.getColorAttachment(texture);
751+
colorAttachment.loadOp = loadOp;
752+
colorAttachment.storeOp = storeOp;
753+
754+
const passDescriptor: GPURenderPassDescriptor = {
755+
colorAttachments: [colorAttachment],
756+
};
757+
758+
const success = !transientTexture || (loadOp === 'clear' && storeOp === 'discard');
759+
760+
t.tryRenderPass(success, passDescriptor);
761+
});
762+
721763
g.test('color_attachments,non_multisampled')
722764
.desc(
723765
`
@@ -1042,11 +1084,17 @@ g.test('depth_stencil_attachment,loadOp_storeOp_match_depthReadOnly_stencilReadO
10421084
- if the format has a depth aspect:
10431085
- if depthReadOnly is true
10441086
- depthLoadOp and depthStoreOp must not be provided
1087+
- if usage includes TRANSIENT_ATTACHMENT
1088+
- depthLoadOp must be clear
1089+
- depthStoreOp must be discard
10451090
- else:
10461091
- depthLoadOp and depthStoreOp must be provided
10471092
- if the format has a stencil aspect:
10481093
- if stencilReadOnly is true
10491094
- stencilLoadOp and stencilStoreOp must not be provided
1095+
- if usage includes TRANSIENT_ATTACHMENT
1096+
- stencilLoadOp must be clear
1097+
- stencilStoreOp must be discard
10501098
- else:
10511099
- stencilLoadOp and stencilStoreOp must be provided
10521100
`
@@ -1055,6 +1103,7 @@ g.test('depth_stencil_attachment,loadOp_storeOp_match_depthReadOnly_stencilReadO
10551103
u
10561104
.combine('format', kDepthStencilFormats)
10571105
.beginSubcases() // Note: It's easier to debug if you comment this line out as you can then run an individual case.
1106+
.combine('transientTexture', [true, false])
10581107
.combine('depthReadOnly', [undefined, true, false])
10591108
.combine('depthLoadOp', [undefined, 'clear', 'load'] as GPULoadOp[])
10601109
.combine('depthStoreOp', [undefined, 'discard', 'store'] as GPUStoreOp[])
@@ -1065,6 +1114,7 @@ g.test('depth_stencil_attachment,loadOp_storeOp_match_depthReadOnly_stencilReadO
10651114
.fn(t => {
10661115
const {
10671116
format,
1117+
transientTexture,
10681118
depthReadOnly,
10691119
depthLoadOp,
10701120
depthStoreOp,
@@ -1075,10 +1125,13 @@ g.test('depth_stencil_attachment,loadOp_storeOp_match_depthReadOnly_stencilReadO
10751125

10761126
t.skipIfTextureFormatNotSupported(format);
10771127

1128+
const usage = transientTexture
1129+
? GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TRANSIENT_ATTACHMENT
1130+
: GPUTextureUsage.RENDER_ATTACHMENT;
10781131
const depthAttachment = t.createTextureTracked({
10791132
format,
10801133
size: { width: 1, height: 1, depthOrArrayLayers: 1 },
1081-
usage: GPUTextureUsage.RENDER_ATTACHMENT,
1134+
usage,
10821135
});
10831136
const depthAttachmentView = depthAttachment.createView();
10841137

@@ -1116,9 +1169,17 @@ g.test('depth_stencil_attachment,loadOp_storeOp_match_depthReadOnly_stencilReadO
11161169
const hasNeitherDepthOps = !depthLoadOp && !depthStoreOp;
11171170
const hasNeitherStencilOps = !stencilLoadOp && !stencilStoreOp;
11181171

1119-
const goodDepthCombo = hasDepth && !depthReadOnly ? hasBothDepthOps : hasNeitherDepthOps;
1172+
const validTransientDepth =
1173+
!transientTexture || (depthLoadOp === 'clear' && depthStoreOp === 'discard');
1174+
const validTransientStencil =
1175+
!transientTexture || (stencilLoadOp === 'clear' && stencilStoreOp === 'discard');
1176+
1177+
const goodDepthCombo =
1178+
hasDepth && !depthReadOnly ? hasBothDepthOps && validTransientDepth : hasNeitherDepthOps;
11201179
const goodStencilCombo =
1121-
hasStencil && !stencilReadOnly ? hasBothStencilOps : hasNeitherStencilOps;
1180+
hasStencil && !stencilReadOnly
1181+
? hasBothStencilOps && validTransientStencil
1182+
: hasNeitherStencilOps;
11221183

11231184
const shouldError = !goodAspectSettingsPresent || !goodDepthCombo || !goodStencilCombo;
11241185

src/webgpu/capability_info.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ export const kTextureUsageInfo: {
210210
[GPUConst.TextureUsage.TEXTURE_BINDING]: {},
211211
[GPUConst.TextureUsage.STORAGE_BINDING]: {},
212212
[GPUConst.TextureUsage.RENDER_ATTACHMENT]: {},
213+
[GPUConst.TextureUsage.TRANSIENT_ATTACHMENT]: {},
213214
};
214215
/** List of all GPUTextureUsage values. */
215216
export const kTextureUsages = numericKeysOf<GPUTextureUsageFlags>(kTextureUsageInfo);

src/webgpu/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const TextureUsage = {
2525
STORAGE_BINDING: 0x08,
2626
STORAGE: 0x08,
2727
RENDER_ATTACHMENT: 0x10,
28+
TRANSIENT_ATTACHMENT: 0x20,
2829
} as const;
2930
checkType<typeof GPUTextureUsage>(TextureUsage);
3031

0 commit comments

Comments
 (0)