Skip to content

Commit efcca9a

Browse files
authored
TSL: Ensure 4 byte alignment for instancedArray() and attributeArray() (#31146)
* fix ensure 4 byte alignment * cleanup
1 parent d1e71ae commit efcca9a

File tree

3 files changed

+22
-3
lines changed

3 files changed

+22
-3
lines changed

src/extras/DataUtils.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,23 @@ class DataUtils {
207207

208208
}
209209

210+
/**
211+
* Aligns a given byte length to the nearest 4-byte boundary.
212+
*
213+
* This function ensures that the returned byte length is a multiple of 4,
214+
* which is often required for memory alignment in certain systems or formats.
215+
*
216+
* @param {number} byteLength - The original byte length to align.
217+
* @returns {number} The aligned byte length, which is a multiple of 4.
218+
*/
219+
static alignTo4ByteBoundary( byteLength ) {
220+
221+
// ensure 4 byte alignment, see #20441
222+
223+
return byteLength + ( ( 4 - ( byteLength % 4 ) ) % 4 );
224+
225+
}
226+
210227
}
211228

212229
export {

src/nodes/accessors/Arrays.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import StorageInstancedBufferAttribute from '../../renderers/common/StorageInsta
22
import StorageBufferAttribute from '../../renderers/common/StorageBufferAttribute.js';
33
import { storage } from './StorageBufferNode.js';
44
import { getLengthFromType, getTypedArrayFromType } from '../core/NodeUtils.js';
5+
import { DataUtils } from '../../extras/DataUtils.js';
56

67
/**
78
* TSL function for creating a storage buffer node with a configured `StorageBufferAttribute`.
@@ -18,7 +19,7 @@ export const attributeArray = ( count, type = 'float' ) => {
1819

1920
if ( type.isStruct === true ) {
2021

21-
itemSize = type.layout.getLength();
22+
itemSize = DataUtils.alignTo4ByteBoundary( type.layout.getLength() );
2223
typedArray = getTypedArrayFromType( 'float' );
2324

2425
} else {
@@ -50,7 +51,7 @@ export const instancedArray = ( count, type = 'float' ) => {
5051

5152
if ( type.isStruct === true ) {
5253

53-
itemSize = type.layout.getLength();
54+
itemSize = DataUtils.alignTo4ByteBoundary( type.layout.getLength() );
5455
typedArray = getTypedArrayFromType( 'float' );
5556

5657
} else {

src/renderers/webgpu/utils/WebGPUAttributeUtils.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { GPUInputStepMode } from './WebGPUConstants.js';
22

33
import { Float16BufferAttribute } from '../../../core/BufferAttribute.js';
4+
import { DataUtils } from '../../../extras/DataUtils.js';
45

56
const typedArraysToVertexFormatPrefix = new Map( [
67
[ Int8Array, [ 'sint8', 'snorm8' ]],
@@ -113,7 +114,7 @@ class WebGPUAttributeUtils {
113114

114115
}
115116

116-
const size = array.byteLength + ( ( 4 - ( array.byteLength % 4 ) ) % 4 ); // ensure 4 byte alignment, see #20441
117+
const size = DataUtils.alignTo4ByteBoundary( array.byteLength );
117118

118119
buffer = device.createBuffer( {
119120
label: bufferAttribute.name,

0 commit comments

Comments
 (0)