Byte Engine Docs

Intrinsics

Find BESL intrinsic names, signatures, stage availability, and behavior.

Intrinsics are typed built-in calls that Byte Engine lowers to platform code. The overloads are intentionally narrow. Use one of the signatures listed here instead of assuming that a native shading-language overload is available.

Shared intrinsics

BESL doesn't restrict the intrinsics in this section to one shader stage. The target language and device must still support the operation in the stage where you use it.

Math

NameSignatureExplanation
minmin(f16, f16) -> f16; min(f32, f32) -> f32Returns the smaller argument.
maxmax(f16, f16) -> f16; max(f32, f32) -> f32; max(vec2f, vec2f) -> vec2f; max(vec3f, vec3f) -> vec3fReturns the component-wise larger argument.
clampclamp(f16, f16, f16) -> f16; clamp(f32, f32, f32) -> f32; clamp(vec3f, vec3f, vec3f) -> vec3fLimits the first argument to the inclusive minimum and maximum.
log2log2(vec3f) -> vec3fReturns the component-wise base-2 logarithm.
powpow(f16, f16) -> f16; pow(f32, f32) -> f32; pow(vec3f, vec3f) -> vec3fRaises each value to its matching exponent.
absabs(f16) -> f16; abs(f32) -> f32; abs(vec2f16) -> vec2f16; abs(vec2f) -> vec2fReturns the absolute value.
sqrtsqrt(f16) -> f16; sqrt(f32) -> f32Returns the square root.
expexp(f32) -> f32; exp(vec3f) -> vec3fReturns the natural exponential.
sinsin(f32) -> f32Returns the sine of an angle in radians.
coscos(f32) -> f32Returns the cosine of an angle in radians.
asinasin(f32) -> f32Returns the inverse sine in radians.
atan2atan2(f32 y, f32 x) -> f32Returns the quadrant-aware angle of y / x in radians.
floorfloor(f32) -> f32Rounds down to the nearest integer-valued float.
sincossincos(f32) -> vec2fReturns sine in x and cosine in y.
tantan(f32) -> f32Returns the tangent of an angle in radians.
roundround(f16) -> f16; round(vec2f16) -> vec2f16; round(vec2f) -> vec2fRounds to the nearest integer-valued float.
round_to_i32round_to_i32(vec2f) -> vec2iRounds both components and converts them to signed integers.
fmafma(f32, f32, f32) -> f32; fma(vec2f, vec2f, vec2f) -> vec2f; fma(vec3f, vec3f, vec3f) -> vec3f; fma(vec4f, vec4f, vec4f) -> vec4fMultiplies the first two arguments and adds the third.
fractfract(f32) -> f32Returns the fractional part.
radiansradians(f32) -> f32Converts degrees to radians.
inversesqrtinversesqrt(f32) -> f32Returns the reciprocal square root.
stepstep(f32 edge, f32 value) -> f32Returns 0.0 below the edge and 1.0 otherwise.
smoothstepsmoothstep(f32 edge0, f32 edge1, f32 value) -> f32Returns smooth Hermite interpolation between two edges.
mixmix(f32 left, f32 right, f32 factor) -> f32Linearly interpolates between two values.
dotdot(vec2f, vec2f) -> f32; dot(vec3f, vec3f) -> f32; dot(vec4f, vec4f) -> f32; dot(vec2f16, vec2f16) -> f16; dot(vec3f16, vec3f16) -> f16; dot(vec4f16, vec4f16) -> f16Returns the vector dot product.
crosscross(vec3f, vec3f) -> vec3fReturns the three-dimensional cross product.
lengthlength(vec3f) -> f32; length(vec4f) -> f32; length(vec2f16) -> f16; length(vec3f16) -> f16; length(vec4f16) -> f16Returns the vector magnitude.
normalizenormalize(vec3f) -> vec3f; normalize(vec4f) -> vec4f; normalize(vec2f16) -> vec2f16; normalize(vec3f16) -> vec3f16; normalize(vec4f16) -> vec4f16Returns a unit-length vector in the same direction.
reflectreflect(vec4f incident, vec4f normal) -> vec4fReflects the incident vector around the normal.

Constructors and casts

Call a vector, matrix, struct, or array type to construct a value. The table lists the explicit conversion overloads registered as intrinsics.

NameSignatureExplanation
f16f16(f16) -> f16; f16(f32) -> f16; f16(u32) -> f16; f16(i32) -> f16Converts a supported scalar to half precision.
u16u16(u32) -> u16Narrows an unsigned integer to 16 bits.
f32f32(f16) -> f32; f32(u32) -> f32; f32(i32) -> f32Converts a supported scalar to single precision.
u32u32(u8) -> u32; u32(u16) -> u32; u32(u32) -> u32; u32(i32) -> u32; u32(f16) -> u32; u32(f32) -> u32Converts a supported scalar to a 32-bit unsigned integer.
vec2f16vec2f16(vec2f) -> vec2f16; vec2f16(vec2f16) -> vec2f16Converts a two-component float vector to half precision.
vec3f16vec3f16(vec3f) -> vec3f16; vec3f16(vec3f16) -> vec3f16Converts a three-component float vector to half precision.
vec4f16vec4f16(vec4f) -> vec4f16; vec4f16(vec4f16) -> vec4f16Converts a four-component float vector to half precision.
vec2fvec2f(vec2f16) -> vec2fConverts a two-component half vector to single precision.
vec3fvec3f(vec3f16) -> vec3fConverts a three-component half vector to single precision.
vec4fvec4f(vec4f16) -> vec4f; vec4f(packed_vec4f) -> vec4fConverts a four-component half or packed vector to an arithmetic float vector.
packed_vec4fpacked_vec4f(vec4f) -> packed_vec4fConverts an arithmetic vector to scalar-aligned storage.

Texture operations

NameSignatureExplanation
samplesample(Texture2D, vec2f uv) -> vec4fSamples a 2D texture with implicit derivatives.
texture_lodtexture_lod(Texture2D, vec2f uv) -> vec4f; texture_lod(Texture2D, vec2f uv, f32 lod) -> vec4f; texture_lod(Texture3D, vec3f uv) -> vec4f; texture_lod(TextureCube, vec3f direction, f32 lod) -> vec4fSamples a texture through the explicit-LOD path. The two-argument overload uses the default level.
texture_cube_array_lodtexture_cube_array_lod(TextureCubeArray, vec3f direction, u32 cube, f32 lod) -> vec4fSamples one cube and mip level from a cube array.
downsample_mindownsample_min(Texture2D, vec2f uv, f32 lod) -> f32Returns the minimum scalar value in the downsample footprint.
downsample_maxdownsample_max(Texture2D, vec2f uv, f32 lod) -> f32; downsample_max(Texture2DArray, vec2f uv, u32 layer, f32 lod) -> f32Returns the maximum scalar value in the downsample footprint.
fetchfetch(Texture2D, vec2u coord) -> vec4f; fetch(Texture2DArray, vec2u coord, u32 layer) -> vec4fFetches one texel by integer coordinate.
fetch_u32fetch_u32(Texture2D, vec2u coord) -> u32Fetches one unsigned scalar texel.
texture_sizetexture_size(Texture2D) -> vec2u; texture_size(Texture2DArray) -> vec2uReturns the texture width and height.

Storage-image operations

NameSignatureExplanation
image_loadimage_load(StorageImage, vec2u coord) -> vec4fLoads one floating-point texel.
image_load_u32image_load_u32(StorageImage, vec2u coord) -> u32Loads one unsigned scalar texel.
image_sizeimage_size(StorageImage) -> vec2uReturns the image width and height.
guard_image_boundsguard_image_bounds(StorageImage, vec2u coord) -> voidReturns from the current function when the coordinate is outside the image.
writewrite(StorageImage, vec2u coord, vec4f value) -> voidStores one texel.
image_atomic_orimage_atomic_or(StorageImage, vec2u coord, u32 value) -> u32Atomically ORs an unsigned texel and returns its previous value. GLSL, HLSL, and the VM support it; MSL doesn't.

Buffer and workgroup atomics

Use these calls with an atomicu32 buffer member or workgroup value.

NameSignatureExplanation
atomic_addatomic_add(atomicu32, u32 increment) -> u32Atomically adds the increment and returns the previous value.
atomic_compare_exchangeatomic_compare_exchange(atomicu32, u32 expected, u32 desired) -> u32Stores the desired value when the current value equals the expected value, then returns the previous value.
atomic_loadatomic_load(atomicu32) -> u32Atomically reads the current value.
atomic_storeatomic_store(atomicu32, u32 value) -> voidAtomically replaces the current value.

Vertex stage

The vertex stage adds no stage-specific intrinsic names. Use the shared intrinsics above with the inputs and outputs supplied by the render model.

Fragment stage

The fragment stage adds derivative information for this intrinsic:

NameSignatureExplanation
fwidthfwidth(f32 value) -> f32Returns the sum of the absolute horizontal and vertical derivatives. The VM returns deterministic 0.0 because it doesn't execute neighboring fragment lanes.

discard is a fragment-oriented statement, not an intrinsic. See control flow.

Compute stage

NameSignatureExplanation
thread_idthread_id() -> vec2uReturns the global two-dimensional compute invocation coordinate.
thread_idxthread_idx() -> u32Returns the linear invocation index inside the local workgroup.
threadgroup_positionthreadgroup_position() -> u32Returns the workgroup position.
workgroup_barrierworkgroup_barrier() -> voidSynchronizes workgroup-shared reads and writes across participating invocations.
subgroup_lane_indexsubgroup_lane_index() -> u32Returns the lane index in the current subgroup.
subgroup_ballotsubgroup_ballot(bool predicate) -> vec4uReturns a bit mask for lanes whose predicate is true.
subgroup_ballot_anysubgroup_ballot_any(vec4u mask) -> boolReports whether the mask contains at least one lane.
subgroup_ballot_find_lsbsubgroup_ballot_find_lsb(vec4u mask) -> u32Returns the index of the least-significant set lane.
subgroup_ballot_countsubgroup_ballot_count(vec4u mask) -> u32Counts the lanes in a mask.
subgroup_ballot_and_notsubgroup_ballot_and_not(vec4u mask, vec4u removed) -> vec4uRemoves selected lanes from a mask.
subgroup_broadcast_u32subgroup_broadcast_u32(u32 value, u32 source_lane) -> u32Copies an unsigned value from one lane to every participating lane.
subgroup_broadcast_f32subgroup_broadcast_f32(f32 value, u32 source_lane) -> f32Copies a float value from one lane to every participating lane.

Subgroup intrinsics require the target's subgroup or wave capability. BESL's GLSL, HLSL, and MSL generators validate them for compute stages only.

Task stage

NameSignatureExplanation
thread_positionthread_position() -> u32Returns the task invocation's scalar position in the dispatch.
thread_idxthread_idx() -> u32Returns the linear invocation index inside the task workgroup.
workgroup_barrierworkgroup_barrier() -> voidSynchronizes workgroup-shared reads and writes across task invocations.
set_task_mesh_output_countset_task_mesh_output_count(u32 count) -> voidSets the number of mesh workgroups emitted by the task workgroup.

The emitted count must not exceed maximum_mesh_threadgroups in the shader's stage metadata.

Mesh stage

NameSignatureExplanation
threadgroup_positionthreadgroup_position() -> u32Returns the mesh workgroup position.
thread_idxthread_idx() -> u32Returns the linear invocation index inside the mesh workgroup.
set_mesh_output_countsset_mesh_output_counts(u32 vertex_count, u32 primitive_count) -> voidSets the number of vertices and primitives emitted by the workgroup.
set_mesh_vertex_positionset_mesh_vertex_position(u32 vertex_index, vec4f position) -> voidWrites one clip-space vertex position.
set_mesh_triangleset_mesh_triangle(u32 primitive_index, vec3u triangle) -> voidWrites the three vertex indices for one triangle.
set_mesh_primitive_render_target_array_indexset_mesh_primitive_render_target_array_index(u32 primitive_index, u32 array_index) -> voidSelects the render-target array layer for one primitive.

Vertex and primitive counts must stay within maximum_vertices and maximum_primitives in the shader's stage metadata.

Next, read compilation and reflection to see which parts of the program Byte Engine can optimize, reflect, and execute.

On this page