Skip to content

generator

FreeBodyEngine.graphics.gl44.generator #

GLSL 440 core code generator - the GL44 backend's key difference from GL33 is that compute/raytrace shaders here are REAL GL_COMPUTE_SHADER stages (GL 4.3+ has actual glDispatchCompute, writable SSBOs, and image load/store), not GL33's fullscreen-fragment-shader emulation. Vertex/ fragment/geometry codegen, expressions, literals, control flow, etc. don't change at all between GL 3.3 and 4.4, so this subclasses GL33Generator and inherits all of that unchanged - only what compute/raytrace/buffer semantics actually need to differ is overridden here.

IMAGE_FORMAT = {'float': 'r32f', 'int': 'r32i', 'vec2': 'rg32f', 'vec4': 'rgba32f'} module-attribute #

GL44Generator(tree, shader_type=fbusl.ShaderType.FRAGMENT) #

Bases: GL33Generator

Emits GLSL 440 core. Subclasses GL33Generator and inherits its vertex/ fragment/geometry codegen unchanged (only the emitted #version line differs there); compute/raytrace shaders are overridden here to target a real GL_COMPUTE_SHADER stage - real SSBOs and image2D/imageStore instead of GL33's fullscreen-fragment-shader emulation with buffer-texture reads - which is why CAPABILITIES additionally advertises "compute.buffer_write", "compute.image_write", "compute.shared_memory", "compute.barrier" and "compute.atomics" on top of GL33's set.

Sets up GL44-specific codegen state on top of GL33Generator's: a private copy of implementations with sample() renamed to _ENGINE_sample() (GLSL reserves sample as a keyword from version 4.0 on, so GL33's unrenamed helper is a hard syntax error under #version 440); _output_fields, so a compute/raytrace Setter targeting an @output field can be recognized and lowered to imageStore(); and image_bindings, populated the first time generate() runs for a compute/raytrace stage so GL44ComputeShader can read back the same unit numbers baked into the emitted layout(binding=N) declarations.

CAPABILITIES = frozenset({'compute.dispatch', 'compute.invocation_id', 'compute.buffer_read', 'compute.buffer_write', 'compute.image_read', 'compute.image_write', 'compute.shared_memory', 'compute.barrier', 'compute.atomics', 'geometry.native', 'raytrace.query_emulated'}) class-attribute instance-attribute #

image_bindings = {} instance-attribute #

implementations = dict(self.implementations) instance-attribute #

generate() #

Emits the full GLSL source for self.tree: a real compute-shader stage (_generate_compute()) for COMPUTE/RAYTRACE, or GL33's vertex/fragment/geometry codegen otherwise - with #version 330 core swapped for #version 440 core in that inherited output, since nothing else about that codegen path differs between the two backends.

generate_buffer_block(node) #

Generates a layout(std430) buffer block declaration (a real SSBO) for one BufferBlock's fields, each as a native GLSL unsized array (<type> <field>[];) - unlike GL33, which has no real SSBOs and instead emulates buffer reads via samplerBuffer/texelFetch. No require() gate is needed here (unlike GL33's generate_buffer_block()): "compute.buffer_write" is a real capability of this backend, so a non-readonly buffer is simply generated as such rather than rejected. Struct-typed fields aren't supported yet and raise an FBUSL error.

generate_identifier(node) #

Lowers the three compute "invocation id" builtins to GL 4.4's real gl_GlobalInvocationID/gl_WorkGroupID/gl_LocalInvocationID (genuinely uvec3, cast to ivec3 to match what FBUSL's semantic analyser already typed them as) rather than GL33's gl_FragCoord- derived arithmetic emulation. Any other identifier falls through to GL33Generator's IMPLEMENTATIONS-table lookup.

generate_inout(node) #

Routes a compute/raytrace @output field to _generate_image_output() (a real image2D/iimage2D binding, not a GLSL out variable); every other in/out/uniform declaration, in any stage, falls through to GL33Generator's implementation unchanged.

generate_setter(node) #

In a compute/raytrace stage, lowers an assignment to a known @output field into an imageStore() call (padding the value out to a vec4/ivec4 per _pad_to_vec4(), and indexing by gl_GlobalInvocationID.xy) instead of GLSL's plain =, since a compute @output is a bound image, not a writable out variable. Every other assignment, in any stage, falls through to GL33Generator's plain left = right codegen.