Skip to content

cf_make_compute_shader

Category: graphics
GitHub: cute_graphics.h


Creates a compute shader from a file in the shader directory.

CF_ComputeShader cf_make_compute_shader(const char* path);
Parameters Description
path A virtual path to the compute shader source, relative to the shader directory.

Remarks

Compute shaders must use GLSL 450 and follow the SDL_GPU resource set layout convention. Resources must be assigned to specific descriptor sets depending on their type:

For COMPUTE shaders:

    Set 0: Sampled textures, followed by readonly storage textures, followed by readonly storage buffers
    Set 1: Read-write storage textures, followed by read-write storage buffers
    Set 2: Uniform buffers

Example COMPUTE shader:

layout (set = 0, binding = 0) uniform sampler2D u_input;

layout (set = 1, binding = 0, rgba8) uniform writeonly image2D u_output;

layout (set = 2, binding = 0) uniform uniform_block {
    float u_time;
};

layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;

Important notes: - Sampled textures (set 0) are bound via cf_material_set_texture_cs. - Uniforms (set 2) are bound via cf_material_set_uniform_cs. - Read-write storage textures (set 1) are bound via CF_ComputeDispatch::rw_textures. - Readonly storage textures (set 0, after samplers) are bound via CF_ComputeDispatch::ro_textures. - Do NOT use return to exit threads before a barrier() call. All threads in a workgroup must reach barrier() uniformly, or the pipeline will fail to compile on some backends. Instead, guard imageStore and other side-effects behind a bounds check.

GLES3/WebGL2 has no compute stage, so CF emulates one. Each dispatch renders the shader body once per write site as a fragment pass, one fragment per invocation, recording what each invocation writes and where; a second draw per site then scatters the records as points into the destination textures and storage buffers. Every read sees memory as it was before the dispatch, never a write from the same dispatch. A shader runs on GLES3 only when it has: - No shared variables, barrier()/memoryBarrier*(), or atomics. - No storage write inside a loop: each imageStore or buffer assignment runs at most once per invocation. - No vec3/uvec3/ivec3 buffer element writes (1, 2 or 4 components only). Shaders outside this class fail to compile with an error naming the construct. The cost is two passes per write site: one full-screen draw sized to the invocation count plus one point per invocation. Float destinations need EXT_color_buffer_float; without it the write is dropped with a one-time warning.

CF_ComputeShader
cf_dispatch_compute
cf_make_compute_shader_from_source
cf_make_compute_shader_from_bytecode
cf_destroy_compute_shader