Skip to content

Commit 9f1f325

Browse files
Add validation tests for transient attachment usage (#4508)
* Add validation tests for transient attachment usage * Reflect gpuweb/gpuweb#5454 changes * Fix error * Add temporary workaround for typescript * keep depth/stencil aspects checks * Fix flags test
1 parent e7cad01 commit 9f1f325

File tree

5 files changed

+90
-13
lines changed

5 files changed

+90
-13
lines changed

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,11 @@ 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 !==
349+
(GPUConst.TextureUsage.RENDER_ATTACHMENT |
350+
GPUConst.TextureUsage.TRANSIENT_ATTACHMENT))
347351
);
348352
})
349353
)
@@ -1037,6 +1041,11 @@ g.test('texture_usage')
10371041
if (isColorTextureFormat(format) && !isTextureFormatColorRenderable(t.device, format))
10381042
success = false;
10391043
}
1044+
if (usage & GPUTextureUsage.TRANSIENT_ATTACHMENT) {
1045+
if (usage !== (GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TRANSIENT_ATTACHMENT)) {
1046+
success = false;
1047+
}
1048+
}
10401049

10411050
t.expectValidationError(() => {
10421051
t.createTextureTracked(descriptor);

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

Lines changed: 70 additions & 12 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
`
@@ -1039,22 +1081,28 @@ g.test('depth_stencil_attachment,loadOp_storeOp_match_depthReadOnly_stencilReadO
10391081
.desc(
10401082
`
10411083
Test GPURenderPassDepthStencilAttachment Usage:
1042-
- if the format has a depth aspect:
1043-
- if depthReadOnly is true
1044-
- depthLoadOp and depthStoreOp must not be provided
1045-
- else:
1046-
- depthLoadOp and depthStoreOp must be provided
1047-
- if the format has a stencil aspect:
1048-
- if stencilReadOnly is true
1049-
- stencilLoadOp and stencilStoreOp must not be provided
1050-
- else:
1051-
- stencilLoadOp and stencilStoreOp must be provided
1084+
- if the format has a depth aspect and depthReadOnly is false
1085+
- depthLoadOp and depthStoreOp must be provided
1086+
- else:
1087+
- depthLoadOp and depthStoreOp must not be provided
1088+
- if the format has a stencil aspect and stencilReadOnly is false
1089+
- stencilLoadOp and stencilStoreOp must be provided
1090+
- else:
1091+
- stencilLoadOp and stencilStoreOp must not be provided
1092+
- if usage includes TRANSIENT_ATTACHMENT
1093+
- if the format has a depth aspect:
1094+
- depthLoadOp must be clear
1095+
- depthStoreOp must be discard
1096+
- if the format has a stencil aspect:
1097+
- stencilLoadOp must be clear
1098+
- stencilStoreOp must be discard
10521099
`
10531100
)
10541101
.params(u =>
10551102
u
10561103
.combine('format', kDepthStencilFormats)
10571104
.beginSubcases() // Note: It's easier to debug if you comment this line out as you can then run an individual case.
1105+
.combine('transientTexture', [true, false])
10581106
.combine('depthReadOnly', [undefined, true, false])
10591107
.combine('depthLoadOp', [undefined, 'clear', 'load'] as GPULoadOp[])
10601108
.combine('depthStoreOp', [undefined, 'discard', 'store'] as GPUStoreOp[])
@@ -1065,6 +1113,7 @@ g.test('depth_stencil_attachment,loadOp_storeOp_match_depthReadOnly_stencilReadO
10651113
.fn(t => {
10661114
const {
10671115
format,
1116+
transientTexture,
10681117
depthReadOnly,
10691118
depthLoadOp,
10701119
depthStoreOp,
@@ -1075,10 +1124,13 @@ g.test('depth_stencil_attachment,loadOp_storeOp_match_depthReadOnly_stencilReadO
10751124

10761125
t.skipIfTextureFormatNotSupported(format);
10771126

1127+
const usage = transientTexture
1128+
? GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TRANSIENT_ATTACHMENT
1129+
: GPUTextureUsage.RENDER_ATTACHMENT;
10781130
const depthAttachment = t.createTextureTracked({
10791131
format,
10801132
size: { width: 1, height: 1, depthOrArrayLayers: 1 },
1081-
usage: GPUTextureUsage.RENDER_ATTACHMENT,
1133+
usage,
10821134
});
10831135
const depthAttachmentView = depthAttachment.createView();
10841136

@@ -1120,7 +1172,13 @@ g.test('depth_stencil_attachment,loadOp_storeOp_match_depthReadOnly_stencilReadO
11201172
const goodStencilCombo =
11211173
hasStencil && !stencilReadOnly ? hasBothStencilOps : hasNeitherStencilOps;
11221174

1123-
const shouldError = !goodAspectSettingsPresent || !goodDepthCombo || !goodStencilCombo;
1175+
const goodTransient =
1176+
!transientTexture ||
1177+
((!hasDepth || (depthLoadOp === 'clear' && depthStoreOp === 'discard')) &&
1178+
(!hasStencil || (stencilLoadOp === 'clear' && stencilStoreOp === 'discard')));
1179+
1180+
const shouldError =
1181+
!goodAspectSettingsPresent || !goodDepthCombo || !goodStencilCombo || !goodTransient;
11241182

11251183
t.expectValidationError(() => {
11261184
encoder.finish();

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: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ const BufferUsage = {
1717
} as const;
1818
checkType<typeof GPUBufferUsage>(BufferUsage);
1919

20+
declare global {
21+
// MAINTENANCE_TODO: Remove this once TRANSIENT_ATTACHMENT is added to @webgpu/types
22+
interface GPUTextureUsage {
23+
readonly TRANSIENT_ATTACHMENT: GPUFlagsConstant;
24+
}
25+
}
26+
2027
const TextureUsage = {
2128
COPY_SRC: 0x01,
2229
COPY_DST: 0x02,
@@ -25,6 +32,7 @@ const TextureUsage = {
2532
STORAGE_BINDING: 0x08,
2633
STORAGE: 0x08,
2734
RENDER_ATTACHMENT: 0x10,
35+
TRANSIENT_ATTACHMENT: 0x20,
2836
} as const;
2937
checkType<typeof GPUTextureUsage>(TextureUsage);
3038

src/webgpu/idl/constants/flags.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const kTextureUsageExp = {
3535
TEXTURE_BINDING: 0x04,
3636
STORAGE_BINDING: 0x08,
3737
RENDER_ATTACHMENT: 0x10,
38+
TRANSIENT_ATTACHMENT: 0x20,
3839
};
3940
g.test('TextureUsage,count').fn(t => {
4041
t.assertMemberCount(GPUTextureUsage, kTextureUsageExp);

0 commit comments

Comments
 (0)