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).