Skip to content

Operation tests for setImmediates#4558

Open
shaoboyan091 wants to merge 4 commits intogpuweb:mainfrom
shaoboyan091:immediate-operation
Open

Operation tests for setImmediates#4558
shaoboyan091 wants to merge 4 commits intogpuweb:mainfrom
shaoboyan091:immediate-operation

Conversation

@shaoboyan091
Copy link
Contributor

@shaoboyan091 shaoboyan091 commented Jan 12, 2026

Implement operation tests for setImmediates in ComputePassEncoder, RenderPassEncoder, and RenderBundleEncoder.

  • Add basic execution tests for scalar, vector, and struct types.
  • Add tests for partial updates and multiple updates (using range verification).
  • Add tests for pipeline switching (compatible and incompatible).
  • Add tests for large data (maxImmediateSize) with range verification.
  • Add tests for TypedArray arguments with offsets.
  • Add tests for mixing render pass and bundle execution.

Issue: #


Requirements for PR author:

  • All missing test coverage is tracked with "TODO" or .unimplemented().
  • New helpers are /** documented */ and new helper files are found in helper_index.txt.
  • Test behaves as expected in a WebGPU implementation. (If not passing, explain above.)
  • Test have be tested with compatibility mode validation enabled and behave as expected. (If not passing, explain above.)

Requirements for reviewer sign-off:

  • Tests are properly located.
  • Test descriptions are accurate and complete.
  • Tests provide complete coverage (including validation control cases). Missing coverage MUST be covered by TODOs.
  • Tests avoid over-parameterization (see case count report).

When landing this PR, be sure to make any necessary issue status updates.

@github-actions
Copy link

github-actions bot commented Jan 12, 2026

Results for build job (at 1ddbf94):

+webgpu:api,operation,command_buffer,programmable,immediate:basic_execution:* - 51 cases, 51 subcases (~1/case)
+webgpu:api,operation,command_buffer,programmable,immediate:update_data:* - 3 cases, 3 subcases (~1/case)
+webgpu:api,operation,command_buffer,programmable,immediate:pipeline_switch:* - 4 cases, 4 subcases (~1/case)
+webgpu:api,operation,command_buffer,programmable,immediate:use_max_immediate_size:* - 3 cases, 3 subcases (~1/case)
+webgpu:api,operation,command_buffer,programmable,immediate:typed_array_arguments:* - 36 cases, 216 subcases (~6/case)
+webgpu:api,operation,command_buffer,programmable,immediate:multiple_updates_before_draw_or_dispatch:* - 3 cases, 3 subcases (~1/case)
+webgpu:api,operation,command_buffer,programmable,immediate:render_pass_and_bundle_mix:* - 1 cases, 1 subcases (~1/case)
+webgpu:api,operation,command_buffer,programmable,immediate:render_bundle_isolation:* - 1 cases, 1 subcases (~1/case)
-TOTAL: 280650 cases, 2321809 subcases
+TOTAL: 280752 cases, 2322091 subcases

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Implement operation tests for setImmediates in ComputePassEncoder,
RenderPassEncoder, and RenderBundleEncoder.

- Add basic execution tests for scalar, vector, and struct types.
- Add tests for partial updates and multiple updates (using range verification).
- Add tests for pipeline switching (no inheritance).
- Add tests for large data (maxImmediateSize) with range verification.
- Add tests for TypedArray arguments with offsets.
- Add tests for mixing render pass and bundle execution.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@shaoboyan091
Copy link
Contributor Author

Softly ping for review.

@Kangz
Copy link
Collaborator

Kangz commented Mar 6, 2026

The operation tests seem to have good coverage. They became much simpler when the group decided to add validation that all immediates are set instead of defaulting to 0.

@shaoboyan091 shaoboyan091 marked this pull request as draft March 9, 2026 08:45
Copy link
Collaborator

@Kangz Kangz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow Github's code review UI is really annoying to use.

Copy link
Collaborator

@Kangz Kangz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost there

.combine('typedArray', kTypedArrayBufferViewKeys)
.combine('encoderType', kProgrammableEncoderTypes)
.beginSubcases()
.combine('dataOffset', [undefined, 0, 2])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With these params, I don't think that the filter below is ever false?

Also why 2 and not other offsets/sizes? For uint8_t it will be an issue as a size of 2 is not a multiple. Instead can we make the dataSize depend on the BYTES_PER_ELEMENT to be either 1 element or 4 bytes (whichever is smaller)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BYTES_PER_ELEMENT is a good idea, I think I could try param generator.

});
t.device.queue.submit([commandEncoder.finish()]);

const expected = new Uint32Array(16);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just reuse clearsData?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will need to be hosted out of the encodeForPassType but that's ok to avoid copying the same filler pattern code twice.

for (let i = 0; i < 16; i++) clearData[i] = 0xaaaaaaaa + i * 0x11111111;
enc.setImmediates!(0, clearData);

if (dataSize === undefined) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that passing undefined to the argument would cause the default values to be used, is that not the case and we need to make calls with different numbers of parameters?

for (let i = 0; i < 16; i++) expected[i] = 0xaaaaaaaa + i * 0x11111111;
const expectedView = new Uint8Array(expected.buffer);

for (let i = 0; i < actualDataSize; i++) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of replicating the conversion, can we copy from view into the correct spot in expected ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a memcpy utility somewhere in the CTS IIRC

const actualDataSize = dataSize ?? maxElementsIn64Bytes - actualDataOffset;

// Create a typed array buffer. If dataSize is undefined, we shouldn't add padding
// because setImmediates uses the rest of the array, which would exceed our intended size or break the % 4 rule.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The padding of 0 or 4 doesn't improve the % 4 rule because both of these numbers are multiples of 4. We need to make the actualDataSize smaller when BYTES_PER_ELEMENT is no a multiple of 4, so that the dataSize == undefined case passes validation. And then we can add paddingElements on top of that.

@shaoboyan091 shaoboyan091 marked this pull request as ready for review March 13, 2026 02:36
@shaoboyan091 shaoboyan091 requested a review from Kangz March 13, 2026 02:36
@shaoboyan091
Copy link
Contributor Author

I think I've resolved comments. PTAL, thanks !

// Pipeline A always uses vec4<u32> (16 bytes).
const wgslDeclA = 'var<immediate> data: vec4<u32>;';
const copyCodeA = `
let base = outIndex * 4;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did your AI start rewriting this test for some reason?

In any case, base is no longer used here.

const arr = new Ctor(actualDataOffset + actualDataSize + paddingElements);
const view = new DataView(arr.buffer);

// Fill the data region with a recognizable byte pattern.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be a single loop over actualDataSize + elementSize, or better over the byte size of view

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants