Skip to content

Commit bd72ec3

Browse files
committed
Loosen Viewport validation tests to match spec update
1 parent bdee22a commit bd72ec3

File tree

2 files changed

+72
-46
lines changed

2 files changed

+72
-46
lines changed

src/webgpu/api/validation/encoding/cmds/render/dynamic_state.spec.ts

+70-44
Original file line numberDiff line numberDiff line change
@@ -130,71 +130,97 @@ class F extends ValidationTest {
130130

131131
export const g = makeTestGroup(F);
132132

133-
g.test('setViewport,x_y_width_height_nonnegative')
133+
g.test('setViewport,width_height_nonnegative')
134134
.desc(
135-
`Test that the parameters of setViewport to define the box must be non-negative.
135+
`Test that the width and height parameters of setViewport must be non-negative.
136136
137137
TODO Test -0 (it should be valid) but can't be tested because the harness complains about duplicate parameters.
138138
TODO Test the first value smaller than -0`
139139
)
140140
.paramsSubcasesOnly([
141141
// Control case: everything to 0 is ok, covers the empty viewport case.
142-
{ x: 0, y: 0, w: 0, h: 0 },
142+
{ w: 0, h: 0 },
143143

144144
// Test -1
145-
{ x: -1, y: 0, w: 0, h: 0 },
146-
{ x: 0, y: -1, w: 0, h: 0 },
147-
{ x: 0, y: 0, w: -1, h: 0 },
148-
{ x: 0, y: 0, w: 0, h: -1 },
145+
{ w: -1, h: 0 },
146+
{ w: 0, h: -1 },
149147
])
150148
.fn(t => {
151-
const { x, y, w, h } = t.params;
152-
const success = x >= 0 && y >= 0 && w >= 0 && h >= 0;
153-
t.testViewportCall(success, { x, y, w, h, minDepth: 0, maxDepth: 1 });
149+
const { w, h } = t.params;
150+
const success = w >= 0 && h >= 0;
151+
t.testViewportCall(success, { x: 0, y: 0, w, h, minDepth: 0, maxDepth: 1 });
154152
});
155153

156-
g.test('setViewport,xy_rect_contained_in_attachment')
154+
g.test('setViewport,exceeds_attachment_size')
157155
.desc(
158-
'Test that the rectangle defined by x, y, width, height must be contained in the attachments'
156+
`Test that the viewport can exceed the attachment size`
157+
)
158+
.paramsSubcasesOnly([
159+
{ attachmentWidth: 3, attachmentHeight: 3 },
160+
{ attachmentWidth: 1024, attachmentHeight: 1024 },
161+
])
162+
.fn(t => {
163+
const { attachmentWidth, attachmentHeight } = t.params;
164+
t.testViewportCall(
165+
true,
166+
{ x: 0, y: 0, w: attachmentWidth+1, h: attachmentHeight+1, minDepth: 0, maxDepth: 1 },
167+
{ width: attachmentWidth, height: attachmentHeight, depthOrArrayLayers: 1 }
168+
);
169+
});
170+
171+
g.test('setViewport,xy_rect_contained_in_bounds')
172+
.desc(
173+
`Test that the rectangle defined by x, y, width, height must be contained in the maximum viewport bounds
174+
and that the viewport size cannot exceed the maximum.`
159175
)
160176
.paramsSubcasesOnly(u =>
161177
u
162178
.combineWithParams([
163-
{ attachmentWidth: 3, attachmentHeight: 5 },
164-
{ attachmentWidth: 5, attachmentHeight: 3 },
165-
{ attachmentWidth: 1024, attachmentHeight: 1 },
166-
{ attachmentWidth: 1, attachmentHeight: 1024 },
167-
])
168-
.combineWithParams([
169-
// Control case: a full viewport is valid.
170-
{ dx: 0, dy: 0, dw: 0, dh: 0 },
171-
172-
// Other valid cases with a partial viewport.
173-
{ dx: 1, dy: 0, dw: -1, dh: 0 },
174-
{ dx: 0, dy: 1, dw: 0, dh: -1 },
175-
{ dx: 0, dy: 0, dw: -1, dh: 0 },
176-
{ dx: 0, dy: 0, dw: 0, dh: -1 },
177-
178-
// Test with a small value that causes the viewport to go outside the attachment.
179-
{ dx: 1, dy: 0, dw: 0, dh: 0 },
180-
{ dx: 0, dy: 1, dw: 0, dh: 0 },
181-
{ dx: 0, dy: 0, dw: 1, dh: 0 },
182-
{ dx: 0, dy: 0, dw: 0, dh: 1 },
179+
// Control case: max viewport is valid.
180+
{ mx: 0, my: 0, dx: 0, dy: 0, dw: 0, dh: 0 },
181+
182+
// Other valid cases
183+
{ mx: -1, my: 0, dx: 0, dy: 0, dw: 0, dh: 0 },
184+
{ mx: -2, my: 0, dx: 0, dy: 0, dw: 0, dh: 0 },
185+
{ mx: 1, my: 0, dx: -1, dy: 0, dw: 0, dh: 0 },
186+
{ mx: 0, my: -1, dx: 0, dy: 0, dw: 0, dh: 0 },
187+
{ mx: 0, my: -2, dx: 0, dy: 0, dw: 0, dh: 0 },
188+
{ mx: 0, my: 1, dx: 0, dy: -1, dw: 0, dh: 0 },
189+
{ mx: 0, my: 0, dx: -1, dy: 0, dw: 0, dh: 0 },
190+
{ mx: 0, my: 0, dx: 1, dy: 0, dw: 0, dh: 0 },
191+
{ mx: 0, my: 0, dx: 0, dy: -1, dw: 0, dh: 0 },
192+
{ mx: 0, my: 0, dx: 0, dy: 1, dw: 0, dh: 0 },
193+
{ mx: 1, my: 0, dx: 0, dy: 0, dw: -1, dh: 0 },
194+
{ mx: 0, my: 1, dx: 0, dy: 0, dw: 0, dh: -1 },
195+
196+
// Cases that go outside the allowed bounds
197+
{ mx: -2, my: 0, dx: -1, dy: 0, dw: 0, dh: 0 },
198+
{ mx: 0, my: -2, dx: 0, dy: -1, dw: 0, dh: 0 },
199+
{ mx: 1, my: 0, dx: 0, dy: 0, dw: 0, dh: 0 },
200+
{ mx: 0, my: 1, dx: 0, dy: 0, dw: 0, dh: 0 },
201+
{ mx: 1, my: 0, dx: 1, dy: 0, dw: -1, dh: 0 },
202+
{ mx: 0, my: 1, dx: 0, dy: 1, dw: 0, dh: -1 },
203+
204+
// Cases that exceed the max viewport size
205+
{ mx: 0, my: 0, dx: 0, dy: 0, dw: 1, dh: 0 },
206+
{ mx: 0, my: 0, dx: 0, dy: 0, dw: 0, dh: 1 },
183207
])
184208
)
185209
.fn(t => {
186-
const { attachmentWidth, attachmentHeight, dx, dy, dw, dh } = t.params;
187-
const x = dx;
188-
const y = dy;
189-
const w = attachmentWidth + dw;
190-
const h = attachmentWidth + dh;
191-
192-
const success = x + w <= attachmentWidth && y + h <= attachmentHeight;
193-
t.testViewportCall(
194-
success,
195-
{ x, y, w, h, minDepth: 0, maxDepth: 1 },
196-
{ width: attachmentWidth, height: attachmentHeight, depthOrArrayLayers: 1 }
197-
);
210+
const { mx, my, dx, dy } = t.params;
211+
const maxViewportSize = t.device.limits.maxTextureDimension2D;
212+
const maxViewportBounds = maxViewportSize * 2;
213+
214+
const x = maxViewportSize * mx + dx;
215+
const y = maxViewportSize * my + dy;
216+
const w = maxViewportSize;
217+
const h = maxViewportSize;
218+
219+
const inBounds = x >= -maxViewportBounds && y >= -maxViewportBounds &&
220+
x + w <= maxViewportBounds - 1 && y + h <= maxViewportBounds -1;
221+
const validSize = w <= maxViewportSize && h <= maxViewportSize;
222+
const success = inBounds && validSize;
223+
t.testViewportCall(success, { x, y, w, h, minDepth: 0, maxDepth: 1 });
198224
});
199225

200226
g.test('setViewport,depth_rangeAndOrder')

src/webgpu/listing_meta.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -499,8 +499,8 @@
499499
"webgpu:api,validation,encoding,cmds,render,dynamic_state:setScissorRect,xy_rect_contained_in_attachment:*": { "subcaseMS": 1.325 },
500500
"webgpu:api,validation,encoding,cmds,render,dynamic_state:setStencilReference:*": { "subcaseMS": 3.450 },
501501
"webgpu:api,validation,encoding,cmds,render,dynamic_state:setViewport,depth_rangeAndOrder:*": { "subcaseMS": 1.667 },
502-
"webgpu:api,validation,encoding,cmds,render,dynamic_state:setViewport,x_y_width_height_nonnegative:*": { "subcaseMS": 0.400 },
503-
"webgpu:api,validation,encoding,cmds,render,dynamic_state:setViewport,xy_rect_contained_in_attachment:*": { "subcaseMS": 0.200 },
502+
"webgpu:api,validation,encoding,cmds,render,dynamic_state:setViewport,width_height_nonnegative:*": { "subcaseMS": 0.400 },
503+
"webgpu:api,validation,encoding,cmds,render,dynamic_state:setViewport,xy_rect_contained_in_bounds:*": { "subcaseMS": 0.200 },
504504
"webgpu:api,validation,encoding,cmds,render,indirect_draw:indirect_buffer,device_mismatch:*": { "subcaseMS": 2.000 },
505505
"webgpu:api,validation,encoding,cmds,render,indirect_draw:indirect_buffer_state:*": { "subcaseMS": 2.708 },
506506
"webgpu:api,validation,encoding,cmds,render,indirect_draw:indirect_buffer_usage:*": { "subcaseMS": 2.733 },

0 commit comments

Comments
 (0)