Skip to content

compute

FreeBodyEngine.graphics.gl44.compute #

The GL44 "compute" backend: real GL_COMPUTE_SHADER stages dispatched via glDispatchCompute, with SSBOs for buffer blocks and image2D/imageStore for @output fields - no fullscreen-quad emulation needed (see graphics/gl33/compute.py for that emulation and why GL33 needs it).

Same public interface as GLComputeShader (graphics/gl33/compute.py) - code written against ComputeShader doesn't change when swapping which backend constructs it.

GL_IMAGE_FORMAT_ENUM = {'r32f': GL_R32F, 'r32i': GL_R32I, 'rg32f': GL_RG32F, 'rgba32f': GL_RGBA32F} module-attribute #

GL_IMAGE_READ_FORMAT = {'r32f': (GL_RED, GL_FLOAT, 1), 'r32i': (GL_RED_INTEGER, GL_INT, 1), 'rg32f': (GL_RG, GL_FLOAT, 2), 'rgba32f': (GL_RGBA, GL_FLOAT, 4)} module-attribute #

GL44ComputeShader(source, injector=None, shader_type=ShaderType.COMPUTE) #

Bases: ComputeShader

The GL 4.4 implementation of ComputeShader: compiles FBUSL straight to a real GL_COMPUTE_SHADER and runs it via glDispatchCompute, with buffer blocks backed by real SSBOs and @output fields written through image2D/imageStore rather than GL33's fullscreen-draw + framebuffer- attachment emulation (see graphics/gl33/compute.py).

Compiles source (keeping the GL44Generator instance around via _compile_and_keep_generator, since its image_bindings mapping is needed after compiling) into a linked compute program, introspects its uniforms, and records each @output field's image unit/format so dispatch() can (re)create backing textures sized to whatever width/height it's called with.

local_size = self._generator._local_size() instance-attribute #

shader_type = shader_type instance-attribute #

uniforms = {} instance-attribute #

bind_buffer(block, field, buffer) #

Binds buffer to the block (the field argument is kept only for interface parity with GLComputeShader - a real SSBO backs the whole block at once, not one field, since GLSL native array indexing means every field of the block lives in the same backing buffer).

blit_to_screen(name, size=None) #

Blits @output field name's texture directly to whatever framebuffer is currently bound (0 = the screen), optionally scaling to size. Wraps the output texture in a scratch one-off read FBO just for the blit rather than pulling in the full Framebuffer class, since Framebuffer always creates (and owns) its own textures instead of wrapping an existing one.

destroy() #

Releases every GPU resource this kernel owns: its SSBOs, its @output backing textures, and the linked compute program itself.

dispatch(width, height) #

Runs the kernel once per (x, y) in [0, width) x [0, height): binds each @output field's backing texture as an image unit (glBindImageTexture, recreating them first if width/height changed since the last dispatch), sets the DISPATCH_SIZE/TIME builtins if the kernel declares them, and issues glDispatchCompute with enough work groups (rounded up) to cover the requested size. Ends with a full glMemoryBarrier, since - unlike GL33's fixed-pipeline emulation, where a draw call's output is already ordered before whatever runs after it - SSBO writes and image stores here aren't otherwise guaranteed visible to a subsequent read.

get_output_texture(name) #

Exposes @output field name's backing GL texture as an engine-level Texture (via TextureManager.wrap_external_texture), so a compute result can feed into the ordinary material/rendering pipeline without a CPU readback.

read_output(name) #

Synchronously reads back @output field name's texture (glGetTexImage) into a (height, width, channels) numpy array, typed int32 or float32 to match the field's declared image format.

set_uniform(name, value) #

Sets uniform name on this kernel's program, via the same glUniform*-dispatch table GL44Shader uses (set_gl_uniform).