Skip to content

Commit b261c86

Browse files
authored
TSL: Fix bitcast type resolver (#31746)
* fix bitcast on WebGPU * remove comments * simpler method * remove extraneous conditional * allow for possibility of future MathNode operations whose b and ctypes are not necessarily of type node * fix spacing * add bitcast node * add bitcastNode * use NodeProxyIntent * remove functions * add getBitcastMethod simplify bitcastNode generate * fix spacing * add to nodes export
1 parent 4047f2e commit b261c86

File tree

6 files changed

+124
-13
lines changed

6 files changed

+124
-13
lines changed

src/nodes/Nodes.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ export { default as MemberNode } from './utils/MemberNode.js';
5757
export { default as DebugNode } from './utils/DebugNode.js';
5858
export { default as EventNode } from './utils/EventNode.js';
5959

60+
// math
61+
export { default as BitcastNode } from './math/BitcastNode.js';
62+
6063
// accessors
6164
export { default as UniformArrayNode } from './accessors/UniformArrayNode.js';
6265
export { default as BufferAttributeNode } from './accessors/BufferAttributeNode.js';

src/nodes/TSL.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export * from './core/OutputStructNode.js';
1919
export * from './core/MRTNode.js';
2020

2121
// math
22+
export * from './math/BitcastNode.js';
2223
export * from './math/Hash.js';
2324
export * from './math/MathUtils.js';
2425
export * from './math/TriNoise3D.js';

src/nodes/math/BitcastNode.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import TempNode from '../core/TempNode.js';
2+
import { nodeProxyIntent } from '../tsl/TSLCore.js';
3+
/**
4+
* This node represents an operation that reinterprets the bit representation of a value
5+
* in one type as a value in another type.
6+
*
7+
* @augments TempNode
8+
*/
9+
class BitcastNode extends TempNode {
10+
11+
static get type() {
12+
13+
return 'BitcastNode';
14+
15+
}
16+
17+
/**
18+
* Constructs a new bitcast node.
19+
*
20+
* @param {Node} valueNode - The value to convert.
21+
* @param {string} conversionType - The type to convert to.
22+
*/
23+
constructor( valueNode, conversionType ) {
24+
25+
super();
26+
27+
/**
28+
* The data to bitcast to a new type.
29+
*
30+
* @type {Node}
31+
*/
32+
this.valueNode = valueNode;
33+
34+
/**
35+
* The type the value will be converted to.
36+
*
37+
* @type {string}
38+
* @default null
39+
*/
40+
this.conversionType = conversionType;
41+
42+
/**
43+
* This flag can be used for type testing.
44+
*
45+
* @type {boolean}
46+
* @readonly
47+
* @default true
48+
*/
49+
this.isBitcastNode = true;
50+
51+
}
52+
53+
/**
54+
* The node's type is defined by the conversion type.
55+
*
56+
* @return {string} The node type.
57+
*/
58+
getNodeType() {
59+
60+
return this.conversionType;
61+
62+
}
63+
64+
65+
generate( builder ) {
66+
67+
const type = this.getNodeType( builder );
68+
const inputType = this.valueNode.getNodeType( builder );
69+
70+
return `${builder.getBitcastMethod( type, inputType )}( ${ this.valueNode.build( builder, inputType ) } )`;
71+
72+
73+
}
74+
75+
}
76+
77+
export default BitcastNode;
78+
79+
/**
80+
* Reinterpret the bit representation of a value in one type as a value in another type.
81+
*
82+
* @tsl
83+
* @function
84+
* @param {Node | number} x - The parameter.
85+
* @param {string} y - The new type.
86+
* @returns {Node}
87+
*/
88+
export const bitcast = /*@__PURE__*/ nodeProxyIntent( BitcastNode ).setParameterLength( 2 );

src/nodes/math/MathNode.js

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,6 @@ MathNode.INVERSE = 'inverse';
366366

367367
// 2 inputs
368368

369-
MathNode.BITCAST = 'bitcast';
370369
MathNode.EQUALS = 'equals';
371370
MathNode.MIN = 'min';
372371
MathNode.MAX = 'max';
@@ -767,17 +766,6 @@ export const inverse = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.INVERSE
767766

768767
// 2 inputs
769768

770-
/**
771-
* Reinterpret the bit representation of a value in one type as a value in another type.
772-
*
773-
* @tsl
774-
* @function
775-
* @param {Node | number} x - The parameter.
776-
* @param {string} y - The new type.
777-
* @returns {Node}
778-
*/
779-
export const bitcast = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.BITCAST ).setParameterLength( 2 );
780-
781769
/**
782770
* Returns `true` if `x` equals `y`.
783771
*

src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ import { DataTexture } from '../../../textures/DataTexture.js';
1010

1111
const glslMethods = {
1212
textureDimensions: 'textureSize',
13-
equals: 'equal'
13+
equals: 'equal',
14+
bitcast_float_int: 'floatBitsToInt',
15+
bitcast_int_float: 'intBitsToFloat',
16+
bitcast_uint_float: 'uintBitsToFloat',
17+
bitcast_float_uint: 'floatBitsToUint',
1418
};
1519

1620
const precisionLib = {
@@ -134,6 +138,19 @@ class GLSLNodeBuilder extends NodeBuilder {
134138

135139
}
136140

141+
/**
142+
* Returns the bitcast method name for a given input and outputType.
143+
*
144+
* @param {string} type - The output type to bitcast to.
145+
* @param {string} inputType - The input type of the.
146+
* @return {string} The resolved WGSL bitcast invocation.
147+
*/
148+
getBitcastMethod( type, inputType ) {
149+
150+
return glslMethods[ `bitcast_${ inputType }_${ type }` ];
151+
152+
}
153+
137154
/**
138155
* Returns the native snippet for a ternary operation.
139156
*

src/renderers/webgpu/nodes/WGSLNodeBuilder.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1960,6 +1960,20 @@ ${ flowData.code }
19601960

19611961
}
19621962

1963+
/**
1964+
* Returns the bitcast method name for a given input and outputType.
1965+
*
1966+
* @param {string} type - The output type to bitcast to.
1967+
* @return {string} The resolved WGSL bitcast invocation.
1968+
*/
1969+
getBitcastMethod( type ) {
1970+
1971+
const dataType = this.getType( type );
1972+
1973+
return `bitcast<${ dataType }>`;
1974+
1975+
}
1976+
19631977
/**
19641978
* Returns the native snippet for a ternary operation.
19651979
*

0 commit comments

Comments
 (0)