@@ -24,79 +24,52 @@ type SoAInputFor<T extends Record<string, BaseData>> = [keyof T] extends [keyof
2424 : never ;
2525
2626function packedSchemaOf ( schema : BaseData ) : BaseData {
27- const unpacked = undecorate ( schema ) ;
28- return isAtomic ( unpacked ) ? unpacked . inner : unpacked ;
27+ const unpackedSchema = undecorate ( schema ) ;
28+ return isAtomic ( unpackedSchema ) ? unpackedSchema . inner : unpackedSchema ;
2929}
3030
31- function getPackedMatrixLayout ( packedSchema : BaseData ) {
32- if ( ! isMat ( packedSchema ) ) {
33- return undefined ;
34- }
35-
36- const dim = isMat3x3f ( packedSchema ) ? 3 : isMat2x2f ( packedSchema ) ? 2 : 4 ;
37- const packedColumnSize = dim * 4 ;
38-
39- return {
40- dim,
41- packedColumnSize,
42- packedSize : dim * packedColumnSize ,
43- } as const ;
31+ function packedMatrixDimOf ( schema : BaseData ) : 2 | 3 | 4 | undefined {
32+ return isMat3x3f ( schema ) ? 3 : isMat2x2f ( schema ) ? 2 : isMat ( schema ) ? 4 : undefined ;
4433}
4534
4635function packedSizeOf ( schema : BaseData ) : number {
4736 const packedSchema = packedSchemaOf ( schema ) ;
48- const matrixLayout = getPackedMatrixLayout ( packedSchema ) ;
49- if ( matrixLayout ) {
50- return matrixLayout . packedSize ;
37+ const matrixDim = packedMatrixDimOf ( packedSchema ) ;
38+ if ( matrixDim ) {
39+ return matrixDim * matrixDim * 4 ;
5140 }
52-
5341 if ( isWgslArray ( packedSchema ) ) {
5442 return packedSchema . elementCount * packedSizeOf ( packedSchema . elementType ) ;
5543 }
56-
5744 return sizeOf ( packedSchema ) ;
5845}
5946
60- function inferSoAElementCount (
47+ function computeSoAByteLength (
6148 arraySchema : WgslArray ,
6249 soaData : Record < string , ArrayBufferView > ,
6350) : number | undefined {
6451 const structSchema = arraySchema . elementType as WgslStruct ;
6552 let inferredCount : number | undefined ;
6653
67- for ( const key in soaData ) {
54+ for ( const key in structSchema . propTypes ) {
6855 const srcArray = soaData [ key ] ;
6956 const fieldSchema = structSchema . propTypes [ key ] ;
7057 if ( srcArray === undefined || fieldSchema === undefined ) {
7158 continue ;
7259 }
73-
74- const fieldPackedSize = packedSizeOf ( fieldSchema ) ;
75- if ( fieldPackedSize === 0 ) {
60+ const packedFieldSize = packedSizeOf ( fieldSchema ) ;
61+ if ( packedFieldSize === 0 ) {
7662 continue ;
7763 }
78-
79- const fieldElementCount = Math . floor ( srcArray . byteLength / fieldPackedSize ) ;
64+ const fieldElementCount = Math . floor ( srcArray . byteLength / packedFieldSize ) ;
8065 inferredCount =
8166 inferredCount === undefined ? fieldElementCount : Math . min ( inferredCount , fieldElementCount ) ;
8267 }
83-
84- return inferredCount ;
85- }
86-
87- function computeSoAByteLength (
88- arraySchema : WgslArray ,
89- soaData : Record < string , ArrayBufferView > ,
90- ) : number | undefined {
91- const elementCount = inferSoAElementCount ( arraySchema , soaData ) ;
92- if ( elementCount === undefined ) {
68+ if ( inferredCount === undefined ) {
9369 return undefined ;
9470 }
95- const elementStride = roundUp (
96- sizeOf ( arraySchema . elementType ) ,
97- alignmentOf ( arraySchema . elementType ) ,
98- ) ;
99- return elementCount * elementStride ;
71+ const elementStride = roundUp ( sizeOf ( structSchema ) , alignmentOf ( structSchema ) ) ;
72+ return inferredCount * elementStride ;
10073}
10174
10275function writePackedValue (
@@ -108,23 +81,21 @@ function writePackedValue(
10881) : void {
10982 const unpackedSchema = undecorate ( schema ) ;
11083 const packedSchema = isAtomic ( unpackedSchema ) ? unpackedSchema . inner : unpackedSchema ;
111- const matrixLayout = getPackedMatrixLayout ( packedSchema ) ;
112- if ( matrixLayout ) {
113- const gpuColumnStride = roundUp ( matrixLayout . packedColumnSize , alignmentOf ( schema ) ) ;
114-
115- for ( let col = 0 ; col < matrixLayout . dim ; col ++ ) {
84+ const matrixDim = packedMatrixDimOf ( packedSchema ) ;
85+ if ( matrixDim ) {
86+ const packedColumnSize = matrixDim * 4 ;
87+ const gpuColumnStride = roundUp ( packedColumnSize , alignmentOf ( schema ) ) ;
88+ for ( let col = 0 ; col < matrixDim ; col ++ ) {
11689 target . set (
11790 srcBytes . subarray (
118- srcOffset + col * matrixLayout . packedColumnSize ,
119- srcOffset + col * matrixLayout . packedColumnSize + matrixLayout . packedColumnSize ,
91+ srcOffset + col * packedColumnSize ,
92+ srcOffset + col * packedColumnSize + packedColumnSize ,
12093 ) ,
12194 dstOffset + col * gpuColumnStride ,
12295 ) ;
12396 }
124-
12597 return ;
12698 }
127-
12899 if ( isWgslArray ( unpackedSchema ) ) {
129100 const packedElementSize = packedSizeOf ( unpackedSchema . elementType ) ;
130101 const gpuElementStride = roundUp (
@@ -141,10 +112,8 @@ function writePackedValue(
141112 srcOffset + i * packedElementSize ,
142113 ) ;
143114 }
144-
145115 return ;
146116 }
147-
148117 target . set ( srcBytes . subarray ( srcOffset , srcOffset + sizeOf ( packedSchema ) ) , dstOffset ) ;
149118}
150119
@@ -156,7 +125,6 @@ function scatterSoA(
156125 endOffset : number ,
157126) : void {
158127 const structSchema = arraySchema . elementType as WgslStruct ;
159- const offsets = offsetsForProps ( structSchema ) ;
160128 const elementStride = roundUp ( sizeOf ( structSchema ) , alignmentOf ( structSchema ) ) ;
161129 invariant (
162130 startOffset % elementStride === 0 ,
@@ -165,6 +133,7 @@ function scatterSoA(
165133 const startElement = Math . floor ( startOffset / elementStride ) ;
166134 const endElement = Math . min ( arraySchema . elementCount , Math . ceil ( endOffset / elementStride ) ) ;
167135 const elementCount = Math . max ( 0 , endElement - startElement ) ;
136+ const offsets = offsetsForProps ( structSchema ) ;
168137
169138 for ( const key in structSchema . propTypes ) {
170139 const fieldSchema = structSchema . propTypes [ key ] ;
@@ -173,12 +142,10 @@ function scatterSoA(
173142 }
174143 const srcArray = soaData [ key ] ;
175144 invariant ( srcArray !== undefined , `Missing SoA data for field '${ key } '` ) ;
176-
177145 const fieldOffset = offsets [ key ] ?. offset ;
178146 invariant ( fieldOffset !== undefined , `Field ${ key } not found in struct schema` ) ;
179- const srcBytes = new Uint8Array ( srcArray . buffer , srcArray . byteOffset , srcArray . byteLength ) ;
180-
181147 const packedFieldSize = packedSizeOf ( fieldSchema ) ;
148+ const srcBytes = new Uint8Array ( srcArray . buffer , srcArray . byteOffset , srcArray . byteLength ) ;
182149 for ( let i = 0 ; i < elementCount ; i ++ ) {
183150 writePackedValue (
184151 target ,
0 commit comments