Skip to content

Commit 8cf6c0d

Browse files
authored
impr: Depreacte the partialWrite API and add patch API that better matches the write features (#2355)
1 parent 4636de8 commit 8cf6c0d

File tree

46 files changed

+810
-418
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+810
-418
lines changed

apps/typegpu-docs/src/content/docs/fundamentals/buffers.mdx

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -364,22 +364,21 @@ buffer.write([d.vec3u(4, 5, 6)], {
364364
```
365365

366366
:::note
367-
In this particular case the `writePartial` method described in the next section would be a more convenient option, but the `startOffset` and `endOffset` options are useful for writing bigger slices of data.
367+
In this particular case the `patch` method described in the next section would be a more convenient option, but the `startOffset` and `endOffset` options are useful for writing bigger slices of data.
368368
:::
369369

370-
### Partial writes
370+
### Patching buffers
371371

372-
When you want to update only a subset of a buffer’s fields, you can use the `.writePartial(data)` method. This method updates only the fields provided in the `data` object and leaves the rest unchanged.
372+
When you want to update only a subset of a buffer’s fields, you can use the `.patch(data)` method. This method updates only the fields provided in the `data` object and leaves the rest unchanged.
373373

374374
The format of the `data` value depends on your schema type:
375375

376376
- **For `d.struct` schemas:**
377377
Provide an object with keys corresponding to the subset of the schema’s fields you wish to update.
378378

379379
- **For `d.array` schemas:**
380-
Provide an array of objects. Each object should specify:
381-
- `idx`: the index of the element to update.
382-
- `value`: the new value for that element.
380+
Provide an object with numeric keys as indices mapped to new values (sparse update),
381+
a plain array for full replacement, or a `TypedArray` for byte-level replacement.
383382

384383
```ts twoslash
385384
import tgpu, { d } from 'typegpu';
@@ -394,12 +393,12 @@ const Planet = d.struct({
394393

395394
const planetBuffer = root.createBuffer(Planet);
396395

397-
planetBuffer.writePartial({
396+
planetBuffer.patch({
398397
mass: 123.1,
399-
colors: [
400-
{ idx: 2, value: d.vec3f(1, 0, 0) },
401-
{ idx: 4, value: d.vec3f(0, 0, 1) },
402-
],
398+
colors: {
399+
2: d.vec3f(1, 0, 0),
400+
4: d.vec3f(0, 0, 1),
401+
},
403402
});
404403
```
405404

apps/typegpu-docs/src/content/docs/integration/wesl-interoperability.mdx

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,12 @@ const buffer = root.createBuffer(FishArray(512)).$usage('storage');
124124
// ^?
125125

126126
// Updating the 123rd fish's position
127-
buffer.writePartial([
128-
{
129-
idx: 123,
130-
value: {
131-
state: {
132-
posit
133-
// ^|
134-
},
135-
}
127+
buffer.patch({
128+
123: {
129+
state: {
130+
posit
131+
// ^|
132+
},
136133
}
137-
]);
134+
});
138135
```

apps/typegpu-docs/src/examples/algorithms/genetic-racing/index.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ function updateAspect() {
401401
return;
402402
}
403403
lastAspect = nextAspect;
404-
params.writePartial({ aspect: nextAspect });
404+
params.patch({ aspect: nextAspect });
405405
}
406406

407407
function updatePopulation(nextPopulation: number) {
@@ -410,7 +410,7 @@ function updatePopulation(nextPopulation: number) {
410410
return;
411411
}
412412
population = clamped;
413-
params.writePartial({ population: clamped });
413+
params.patch({ population: clamped });
414414
ga.reinitCurrent(population);
415415
}
416416

@@ -421,7 +421,7 @@ function frame() {
421421
if (pendingEvolve) {
422422
ga.evolve(population);
423423
steps = 0;
424-
params.writePartial({ generation: ga.generation });
424+
params.patch({ generation: ga.generation });
425425
pendingEvolve = false;
426426
}
427427

@@ -430,7 +430,7 @@ function frame() {
430430
pendingEvolve = true;
431431
} else {
432432
const innerSteps = Math.min(stepsToRun, STEPS_PER_DISPATCH);
433-
params.writePartial({ stepsPerDispatch: innerSteps });
433+
params.patch({ stepsPerDispatch: innerSteps });
434434
const dispatchCount = Math.ceil(stepsToRun / innerSteps);
435435

436436
const simEncoder = root.device.createCommandEncoder();
@@ -480,7 +480,7 @@ function applyTrack(result: TrackResult) {
480480
trackTexture.write(
481481
new ImageData(new Uint8ClampedArray(result.data), result.width, result.height),
482482
);
483-
params.writePartial({
483+
params.patch({
484484
spawnX: result.spawn.position[0],
485485
spawnY: result.spawn.position[1],
486486
spawnAngle: result.spawn.angle,
@@ -490,7 +490,7 @@ function applyTrack(result: TrackResult) {
490490

491491
function applyGridSize(W: number, H: number) {
492492
const scale = 5 / Math.max(W, H);
493-
params.writePartial(
493+
params.patch(
494494
Object.fromEntries(
495495
Object.entries(BASE_SPATIAL_PARAMS).map(([k, v]) => [k, v * scale]),
496496
) as typeof BASE_SPATIAL_PARAMS,
@@ -511,7 +511,7 @@ function startSimulation() {
511511
steps = 0;
512512
pendingEvolve = false;
513513
displayedBestFitness = 0;
514-
params.writePartial({ generation: 0 });
514+
params.patch({ generation: 0 });
515515
ga.init();
516516

517517
updateAspect();
@@ -589,7 +589,7 @@ export const controls = defineControls({
589589
max: 0.4,
590590
step: 0.005,
591591
onSliderChange: (value: number) => {
592-
params.writePartial({ mutationRate: value });
592+
params.patch({ mutationRate: value });
593593
},
594594
},
595595
'Mutation strength': {
@@ -598,7 +598,7 @@ export const controls = defineControls({
598598
max: 0.8,
599599
step: 0.01,
600600
onSliderChange: (value: number) => {
601-
params.writePartial({ mutationStrength: value });
601+
params.patch({ mutationStrength: value });
602602
},
603603
},
604604
});

apps/typegpu-docs/src/examples/algorithms/jump-flood-distance/index.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ function runFlood() {
300300

301301
function drawAtPosition(canvasX: number, canvasY: number) {
302302
const rect = canvas.getBoundingClientRect();
303-
brushUniform.writePartial({
303+
brushUniform.patch({
304304
center: d.vec2f((canvasX * width) / rect.width, (canvasY * height) / rect.height),
305305
});
306306
drawSeed.with(resources.maskBindGroup).dispatchThreads(width, height);
@@ -371,7 +371,7 @@ const onMouseDown = (e: MouseEvent) => {
371371
if (e.button !== 0 && e.button !== 2) {
372372
return;
373373
}
374-
brushUniform.writePartial({ erasing: e.button === 2 ? 1 : 0 });
374+
brushUniform.patch({ erasing: e.button === 2 ? 1 : 0 });
375375
isDrawing = true;
376376
lastDrawPos = null;
377377
const rect = canvas.getBoundingClientRect();
@@ -395,7 +395,7 @@ const onTouchStart = (e: TouchEvent) => {
395395
isDrawing = true;
396396
lastDrawPos = null;
397397
const rect = canvas.getBoundingClientRect();
398-
brushUniform.writePartial({ erasing: e.touches.length === 2 ? 1 : 0 });
398+
brushUniform.patch({ erasing: e.touches.length === 2 ? 1 : 0 });
399399
const pos = getTouchPosition(rect, e.touches);
400400
interpolateAndDraw(pos.x, pos.y);
401401
};
@@ -405,7 +405,7 @@ const onTouchMove = (e: TouchEvent) => {
405405
return;
406406
}
407407
e.preventDefault();
408-
brushUniform.writePartial({ erasing: e.touches.length === 2 ? 1 : 0 });
408+
brushUniform.patch({ erasing: e.touches.length === 2 ? 1 : 0 });
409409
const rect = canvas.getBoundingClientRect();
410410
const pos = getTouchPosition(rect, e.touches);
411411
interpolateAndDraw(pos.x, pos.y);
@@ -427,7 +427,7 @@ canvas.addEventListener('touchend', onTouchEnd);
427427
canvas.addEventListener('touchcancel', onTouchEnd);
428428

429429
function updateBrushSize() {
430-
brushUniform.writePartial({
430+
brushUniform.patch({
431431
radius: Math.ceil(Math.min(width, height) * brushSize),
432432
});
433433
}
@@ -449,14 +449,14 @@ export const controls = defineControls({
449449
'Show positive distance': {
450450
initial: true,
451451
onToggleChange(value: boolean) {
452-
paramsUniform.writePartial({ showOutside: value ? 1 : 0 });
452+
paramsUniform.patch({ showOutside: value ? 1 : 0 });
453453
render();
454454
},
455455
},
456456
'Show negative distance': {
457457
initial: false,
458458
onToggleChange(value: boolean) {
459-
paramsUniform.writePartial({ showInside: value ? 1 : 0 });
459+
paramsUniform.patch({ showInside: value ? 1 : 0 });
460460
render();
461461
},
462462
},

apps/typegpu-docs/src/examples/geometry/lines-combinations/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ let subdiv = {
338338
};
339339

340340
const draw = (timeMs: number) => {
341-
uniformsBuffer.writePartial({
341+
uniformsBuffer.patch({
342342
time: timeMs * 1e-3,
343343
});
344344
const colorAttachment: ColorAttachment = {
@@ -453,7 +453,7 @@ export const controls = defineControls({
453453
options: Object.keys(fillOptions),
454454
onSelectChange: async (selected) => {
455455
fillType = fillOptions[selected as keyof typeof fillOptions];
456-
uniformsBuffer.writePartial({ fillType });
456+
uniformsBuffer.patch({ fillType });
457457
},
458458
},
459459
'Subdiv. Level': {

apps/typegpu-docs/src/examples/image-processing/background-segmentation/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ function updateCropBounds(aspectRatio: number) {
198198
uvMaxY = uvMinY + cropHeight;
199199
}
200200
}
201-
paramsUniform.writePartial({
201+
paramsUniform.patch({
202202
cropBounds: d.vec4f(uvMinX, uvMinY, uvMaxX, uvMaxY),
203203
});
204204
}
@@ -313,7 +313,7 @@ export const controls = defineControls({
313313
options: ['mipmaps', 'gaussian'],
314314
async onSelectChange(value) {
315315
useGaussianBlur = value === 'gaussian';
316-
paramsUniform.writePartial({ useGaussian: useGaussianBlur ? 1 : 0 });
316+
paramsUniform.patch({ useGaussian: useGaussianBlur ? 1 : 0 });
317317
},
318318
},
319319
'blur strength': {
@@ -323,7 +323,7 @@ export const controls = defineControls({
323323
step: 1,
324324
onSliderChange(newValue) {
325325
blurStrength = newValue;
326-
paramsUniform.writePartial({ sampleBias: blurStrength });
326+
paramsUniform.patch({ sampleBias: blurStrength });
327327
},
328328
},
329329
'square crop': {

apps/typegpu-docs/src/examples/image-processing/image-tuning/index.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ export const controls = defineControls({
284284
onSelectChange: async (selected) => {
285285
if (selected === 'None') {
286286
currentLUTTexture = defaultLUTTexture;
287-
lut.writePartial({ enabled: 0 });
287+
lut.patch({ enabled: 0 });
288288
} else {
289289
await updateLUT(LUTFiles[selected as keyof typeof LUTFiles]);
290290
}
@@ -297,7 +297,7 @@ export const controls = defineControls({
297297
max: 2.0,
298298
step: 0.1,
299299
onSliderChange(value) {
300-
adjustments.writePartial({ exposure: value });
300+
adjustments.patch({ exposure: value });
301301
render();
302302
},
303303
},
@@ -307,7 +307,7 @@ export const controls = defineControls({
307307
max: 2.0,
308308
step: 0.1,
309309
onSliderChange(value) {
310-
adjustments.writePartial({ contrast: value });
310+
adjustments.patch({ contrast: value });
311311
render();
312312
},
313313
},
@@ -317,7 +317,7 @@ export const controls = defineControls({
317317
max: 2.0,
318318
step: 0.1,
319319
onSliderChange(value) {
320-
adjustments.writePartial({ highlights: value });
320+
adjustments.patch({ highlights: value });
321321
render();
322322
},
323323
},
@@ -327,7 +327,7 @@ export const controls = defineControls({
327327
max: 1.9,
328328
step: 0.1,
329329
onSliderChange(value) {
330-
adjustments.writePartial({ shadows: value });
330+
adjustments.patch({ shadows: value });
331331
render();
332332
},
333333
},
@@ -337,7 +337,7 @@ export const controls = defineControls({
337337
max: 2.0,
338338
step: 0.1,
339339
onSliderChange(value) {
340-
adjustments.writePartial({ saturation: value });
340+
adjustments.patch({ saturation: value });
341341
render();
342342
},
343343
},

apps/typegpu-docs/src/examples/rendering/box-raytracing/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ const runner = (timestamp: number) => {
262262
Math.sin(frame) * cameraDistance + cameraAnchor.z,
263263
);
264264

265-
uniforms.writePartial({
265+
uniforms.patch({
266266
canvasDims: d.vec2f(width, height),
267267
invViewMatrix: mat4.aim(cameraPosition, cameraAnchor, d.vec3f(0, 1, 0), d.mat4x4f()),
268268
});
@@ -300,7 +300,7 @@ export const controls = defineControls({
300300
min: 0.1,
301301
max: 1,
302302
onSliderChange: (value) => {
303-
uniforms.writePartial({
303+
uniforms.patch({
304304
boxSize: value,
305305
});
306306
},
@@ -311,7 +311,7 @@ export const controls = defineControls({
311311
min: 0.2,
312312
max: 2,
313313
onSliderChange: (value) => {
314-
uniforms.writePartial({
314+
uniforms.patch({
315315
materialDensity: value,
316316
});
317317
},

apps/typegpu-docs/src/examples/rendering/clouds/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ resizeObserver.observe(canvas);
9494
let frameId: number;
9595

9696
function render(timestamp: number) {
97-
paramsUniform.writePartial({ time: (timestamp / 1000) % 500 });
97+
paramsUniform.patch({ time: (timestamp / 1000) % 500 });
9898

9999
pipeline
100100
.with(bindGroup)
@@ -137,7 +137,7 @@ export const controls = defineControls({
137137
initial: 'medium',
138138
options: ['very high', 'high', 'medium', 'low', 'very low'],
139139
onSelectChange(value) {
140-
paramsUniform.writePartial(qualityOptions[value]);
140+
paramsUniform.patch(qualityOptions[value]);
141141
},
142142
},
143143
});

0 commit comments

Comments
 (0)