sokol/gfx
sokol_gfx
Types
155Allocator
Allocator :: struct {
alloc_fn: proc(a0: c.size_t, a1: rawptr) -> (rawptr),
a0: c.size_t,
size_t: rawptr,
a1: rawptr,
free_fn: proc(a0: rawptr, a1: rawptr),
a0: rawptr,
a1: rawptr,
user_data: rawptr,
}Sourcesg_allocator
Used in sg_desc to provide custom memory-alloc and -free functions to sokol_gfx.h. If memory management should be overridden, both the alloc_fn and free_fn function must be provided (e.g. it's not valid to override one function but not the other).
Attachments
Attachments :: struct {
colors: [8]View,
resolves: [8]View,
depth_stencil: View,
}Sourcesg_attachments
Used in sg_pass to provide render pass attachment views. Each type of pass attachment has it corresponding view type:
sg_attachments.colors[]: populate with color-attachment views, e.g.:
sg_make_view(&(sg_view_desc){ .color_attachment = { ... }, });
sg_attachments.resolves[]: populate with resolve-attachment views, e.g.:
sg_make_view(&(sg_view_desc){ .resolve_attachment = { ... }, });
sg_attachments.depth_stencil: populate with depth-stencil-attachment views, e.g.:
sg_make_view(&(sg_view_desc){ .depth_stencil_attachment = { ... }, });
Backend
Backend :: enum i32 {
GLCORE = 0,
GLES3 = 1,
D3D11 = 2,
METAL_IOS = 3,
METAL_MACOS = 4,
METAL_SIMULATOR = 5,
WGPU = 6,
VULKAN = 7,
DUMMY = 8,
}Sourcesg_backend
The active 3D-API backend, use the function sg_query_backend() to get the currently active backend.
Bindings
Bindings :: struct {
_: u32,
vertex_buffers: [8]Buffer,
vertex_buffer_offsets: [8]c.int,
index_buffer: Buffer,
index_buffer_offset: c.int,
views: [32]View,
samplers: [12]Sampler,
_: u32,
}Sourcesg_bindings
The sg_bindings structure defines the resource bindings for the next draw call.
To update the resource bindings, call sg_apply_bindings() with a pointer to a populated sg_bindings struct. Note that sg_apply_bindings() must be called after sg_apply_pipeline() and that bindings are not preserved across sg_apply_pipeline() calls, even when the new pipeline uses the same 'bindings layout'.
A resource binding struct contains:
- 1..N vertex buffers
- 1..N vertex buffer offsets
- 0..1 index buffer
- 0..1 index buffer offset
- 0..N resource views (texture-, storage-image, storage-buffer-views)
- 0..N samplers
Where 'N' is defined in the following constants:
- SG_MAX_VERTEXBUFFER_BINDSLOTS
- SG_MAX_VIEW_BINDSLOTS
- SG_MAX_SAMPLER_BINDSLOTS
Note that inside compute passes vertex- and index-buffer-bindings are disallowed.
When using sokol-shdc for shader authoring, the layout(binding=N) for texture-, storage-image- and storage-buffer-bindings directly maps to the views-array index, for instance the following vertex- and fragment-shader interface for sokol-shdc:
@vs vs layout(binding=0) uniform vs_params { ... }; layout(binding=0) readonly buffer ssbo { ... }; layout(binding=1) uniform texture2D vs_tex; layout(binding=0) uniform sampler vs_smp; ... @end
@fs fs layout(binding=1) uniform fs_params { ... }; layout(binding=2) uniform texture2D fs_tex; layout(binding=1) uniform sampler fs_smp; ... @end
...would map to the following sg_bindings struct:
const sg_bindings bnd = { .vertex_buffers[0] = ..., .views[0] = ssbo_view, .views[1] = vs_tex_view, .views[2] = fs_tex_view, .samplers[0] = vs_smp, .samplers[1] = fs_smp, };
...alternatively you can use code-generated slot indices:
const sg_bindings bnd = { .vertex_buffers[0] = ..., .views[VIEW_ssbo] = ssbo_view, .views[VIEW_vs_tex] = vs_tex_view, .views[VIEW_fs_tex] = fs_tex_view, .samplers[SMP_vs_smp] = vs_smp, .samplers[SMP_fs_smp] = fs_smp, };
Resource bindslots for a specific shader/pipeline may have gaps, and an sg_bindings struct may have populated bind slots which are not used by a specific shader. This allows to use the same sg_bindings struct across different shader variants.
When not using sokol-shdc, the bindslot indices in the sg_bindings struct need to match the per-binding reflection info slot indices in the sg_shader_desc struct (for details about that see the sg_shader_desc struct documentation).
The optional buffer offsets can be used to put different unrelated chunks of vertex- and/or index-data into the same buffer objects.
Blend_Factor
Blend_Factor :: enum i32 {
DEFAULT = 0,
ZERO = 1,
ONE = 2,
SRC_COLOR = 3,
ONE_MINUS_SRC_COLOR = 4,
SRC_ALPHA = 5,
ONE_MINUS_SRC_ALPHA = 6,
DST_COLOR = 7,
ONE_MINUS_DST_COLOR = 8,
DST_ALPHA = 9,
ONE_MINUS_DST_ALPHA = 10,
SRC_ALPHA_SATURATED = 11,
BLEND_COLOR = 12,
ONE_MINUS_BLEND_COLOR = 13,
BLEND_ALPHA = 14,
ONE_MINUS_BLEND_ALPHA = 15,
SRC1_COLOR = 16,
ONE_MINUS_SRC1_COLOR = 17,
SRC1_ALPHA = 18,
ONE_MINUS_SRC1_ALPHA = 19,
}Sourcesg_blend_factor
The source and destination factors in blending operations. This is used in the following members when creating a pipeline object:
sg_pipeline_desc .colors[i] .blend .src_factor_rgb .dst_factor_rgb .src_factor_alpha .dst_factor_alpha
The default value is SG_BLENDFACTOR_ONE for source factors, and for the destination SG_BLENDFACTOR_ZERO if the associated blend-op is ADD, SUBTRACT or REVERSE_SUBTRACT or SG_BLENDFACTOR_ONE if the associated blend-op is MIN or MAX.
Blend_Op
Blend_Op :: enum i32 {
DEFAULT = 0,
ADD = 1,
SUBTRACT = 2,
REVERSE_SUBTRACT = 3,
MIN = 4,
MAX = 5,
}Sourcesg_blend_op
Describes how the source and destination values are combined in the fragment blending operation. It is used in the following struct items when creating a pipeline object:
sg_pipeline_desc .colors[i] .blend .op_rgb .op_alpha
The default value is SG_BLENDOP_ADD.
Blend_State
Blend_State :: struct {
enabled: bool,
src_factor_rgb: Blend_Factor,
dst_factor_rgb: Blend_Factor,
op_rgb: Blend_Op,
src_factor_alpha: Blend_Factor,
dst_factor_alpha: Blend_Factor,
op_alpha: Blend_Op,
}SourceBorder_Color
Border_Color :: enum i32 {
DEFAULT = 0,
TRANSPARENT_BLACK = 1,
OPAQUE_BLACK = 2,
OPAQUE_WHITE = 3,
}Sourcesg_border_color
The border color to use when sampling a texture, and the UV wrap mode is SG_WRAP_CLAMP_TO_BORDER.
The default border color is SG_BORDERCOLOR_OPAQUE_BLACK
Buffer
Buffer :: struct {
id: u32,
}SourceResource id typedefs:
sg_buffer: vertex- and index-buffers sg_image: images used as textures and render-pass attachments sg_sampler sampler objects describing how a texture is sampled in a shader sg_shader: vertex- and fragment-shaders and shader interface information sg_pipeline: associated shader and vertex-layouts, and render states sg_view: a resource view object used for bindings and render-pass attachments
Instead of pointers, resource creation functions return a 32-bit handle which uniquely identifies the resource object.
The 32-bit resource id is split into a 16-bit pool index in the lower bits, and a 16-bit 'generation counter' in the upper bits. The index allows fast pool lookups, and combined with the generation-counter it allows to detect 'dangling accesses' (trying to use an object which no longer exists, and its pool slot has been reused for a new object)
The resource ids are wrapped into a strongly-typed struct so that trying to pass an incompatible resource id is a compile error.
Buffer_Desc
Buffer_Desc :: struct {
_: u32,
size: c.size_t,
usage: Buffer_Usage,
data: Range,
label: cstring,
gl_buffers: [2]u32,
mtl_buffers: [2]rawptr,
d3d11_buffer: rawptr,
wgpu_buffer: rawptr,
_: u32,
}Sourcesg_buffer_desc
Creation parameters for sg_buffer objects, used in the sg_make_buffer() call.
The default configuration is:
.size: 0 (must be >0 for buffers without data) .usage { .vertex_buffer = true, .immutable = true } .data.ptr 0 (must be valid for immutable buffers without storage buffer usage) .data.size 0 (must be > 0 for immutable buffers without storage buffer usage) .label 0 (optional string label)
For immutable buffers which are initialized with initial data, keep the .size item zero-initialized, and set the size together with the pointer to the initial data in the .data item.
For immutable or mutable buffers without initial data, keep the .data item zero-initialized, and set the buffer size in the .size item instead.
You can also set both size values, but currently both size values must be identical (this may change in the future when the dynamic resource management may become more flexible).
NOTE: Immutable buffers without storage-buffer-usage must be created with initial content, this restriction doesn't apply to storage buffer usage, because storage buffers may also get their initial content by running a compute shader on them.
NOTE: Buffers without initial data will have undefined content, e.g. do not expect the buffer to be zero-initialized!
ADVANCED TOPIC: Injecting native 3D-API buffers:
The following struct members allow to inject your own GL, Metal or D3D11 buffers into sokol_gfx:
.gl_buffers[SG_NUM_INFLIGHT_FRAMES] .mtl_buffers[SG_NUM_INFLIGHT_FRAMES] .d3d11_buffer
You must still provide all other struct items except the .data item, and these must match the creation parameters of the native buffers you provide. For sg_buffer_desc.usage.immutable buffers, only provide a single native 3D-API buffer, otherwise you need to provide SG_NUM_INFLIGHT_FRAMES buffers (only for GL and Metal, not D3D11). Providing multiple buffers for GL and Metal is necessary because sokol_gfx will rotate through them when calling sg_update_buffer() to prevent lock-stalls.
Note that it is expected that immutable injected buffer have already been initialized with content, and the .content member must be 0!
Also you need to call sg_reset_state_cache() after calling native 3D-API functions, and before calling any sokol_gfx function.
Buffer_Info
Buffer_Info :: struct {
slot: Slot_Info,
update_frame_index: u32,
append_frame_index: u32,
append_pos: c.int,
append_overflow: bool,
num_slots: c.int,
active_slot: c.int,
}SourceBuffer_Location
Buffer_Location :: struct {
buffer: Buffer,
offset: c.size_t,
}Sourcesg_buffer_location
Describes the source or destination location in a buffer.
Buffer_Usage
Buffer_Usage :: struct {
vertex_buffer: bool,
index_buffer: bool,
storage_buffer: bool,
immutable: bool,
dynamic_update: bool,
stream_update: bool,
write_unsealed: bool,
}Sourcesg_buffer_usage
Describes how a buffer object is going to be used:
.vertex_buffer (default: true) the buffer will be bound as vertex buffer via sg_bindings.vertex_buffers[] .index_buffer (default: false) the buffer will be bound as index buffer via sg_bindings.index_buffer .storage_buffer (default: false) the buffer will be bound as storage buffer via storage-buffer-view in sg_bindings.views[] .immutable (default: true) the buffer content will never be updated from the CPU side while in 'valid' resource state (but may be written to by a compute shader) .dynamic_update (default: false) the buffer content will be infrequently updated from the CPU side .stream_update (default: false) the buffer content will be updated each frame from the CPU side .write_unsealed (default: false) when true, creates an immutable buffer in 'unsealed' resource state, unsealed buffers can be populated with data by one or multiple sg_write_buffer_unsealed() calls before being 'sealed' by calling sg_seal_buffer() which transitions from 'unsealed' to 'valid' resource state
Buffer_View_Desc
Buffer_View_Desc :: struct {
buffer: Buffer,
offset: c.int,
}Sourcesg_view_desc
Creation params for sg_view objects, passed into sg_make_view() calls.
View objects are passed into sg_apply_bindings() (for texture-, storage-buffer- and storage-image views), and sg_begin_pass() (for color-, resolve- and depth-stencil-attachment views).
The view type is determined by initializing one of the sub-structs of sg_view_desc:
.texture a texture-view object will be created .image the sg_image parent resource .mip_levels optional mip-level range, keep zero-initialized for the entire mipmap chain .base the first mip level .count number of mip levels, keeping this zero-initialized means 'all remaining mip levels' .slices optional slice range, keep zero-initialized to include all slices .base the first slice .count number of slices, keeping this zero-initializied means 'all remaining slices'
.storage_buffer a storage-buffer-view object will be created .buffer the sg_buffer parent resource, must have been created with sg_buffer_desc.usage.storage_buffer = true .offset optional 256-byte aligned byte-offset into the buffer
.storage_image a storage-image-view object will be created .image the sg_image parent resource, must have been created with sg_image_desc.usage.storage_image = true .mip_level selects the mip-level for the compute shader to write .slice selects the slice for the compute shader to write
.color_attachment a color-attachment-view object will be created .image the sg_image parent resource, must have been created with sg_image_desc.usage.color_attachment = true .mip_level selects the mip-level to render into .slice selects the slice to render into
.resolve_attachment a resolve-attachment-view object will be created .image the sg_image parent resource, must have been created with sg_image_desc.usage.resolve_attachment = true .mip_level selects the mip-level to msaa-resolve into .slice selects the slice to msaa-resolve into
.depth_stencil_attachment a depth-stencil-attachment-view object will be created .image the sg_image parent resource, must have been created with sg_image_desc.usage.depth_stencil_attachment = true .mip_level selects the mip-level to render into .slice selects the slice to render into
Color
Color :: struct {
r: f32,
g: f32,
b: f32,
a: f32,
}Sourcesg_color
An RGBA color value.
Color_Attachment_Action
Color_Attachment_Action :: struct {
load_action: Load_Action,
store_action: Store_Action,
clear_value: Color,
}Sourcesg_pass_action
The sg_pass_action struct defines the actions to be performed at the start and end of a render pass.
- at the start of the pass: whether the render attachments should be cleared,
loaded with their previous content, or start in an undefined state
- for clear operations: the clear value (color, depth, or stencil values)
- at the end of the pass: whether the rendering result should be
stored back into the render attachment or discarded
Color_Mask
Color_Mask :: enum i32 {
DEFAULT = 0,
NONE = 16,
R = 1,
G = 2,
RG = 3,
B = 4,
RB = 5,
GB = 6,
RGB = 7,
A = 8,
RA = 9,
GA = 10,
RGA = 11,
BA = 12,
RBA = 13,
GBA = 14,
RGBA = 15,
}Sourcesg_color_mask
Selects the active color channels when writing a fragment color to the framebuffer. This is used in the members sg_pipeline_desc.colors[i].write_mask when creating a pipeline object.
The default colormask is SG_COLORMASK_RGBA (write all colors channels)
NOTE: since the color mask value 0 is reserved for the default value (SG_COLORMASK_RGBA), use SG_COLORMASK_NONE if all color channels should be disabled.
Color_Target_State
Color_Target_State :: struct {
pixel_format: Pixel_Format,
write_mask: Color_Mask,
blend: Blend_State,
}SourceCommit_Listener
Commit_Listener :: struct {
func: proc(a0: rawptr),
a0: rawptr,
user_data: rawptr,
}Sourcesg_commit_listener
Used with function sg_add_commit_listener() to add a callback which will be called in sg_commit(). This is useful for libraries building on top of sokol-gfx to be notified about when a frame ends (instead of having to guess, or add a manual 'new-frame' function.
Compare_Func
Compare_Func :: enum i32 {
DEFAULT = 0,
NEVER = 1,
LESS = 2,
EQUAL = 3,
LESS_EQUAL = 4,
GREATER = 5,
NOT_EQUAL = 6,
GREATER_EQUAL = 7,
ALWAYS = 8,
}Sourcesg_compare_func
The compare-function for configuring depth- and stencil-ref tests in pipeline objects, and for texture samplers which perform a comparison instead of regular sampling operation.
Used in the following structs:
sg_pipeline_desc .depth .compare .stencil .front.compare .back.compare
sg_sampler_desc .compare
The default compare func for depth- and stencil-tests is SG_COMPAREFUNC_ALWAYS.
The default compare func for samplers is SG_COMPAREFUNC_NEVER.
Cull_Mode
Cull_Mode :: enum i32 {
DEFAULT = 0,
NONE = 1,
FRONT = 2,
BACK = 3,
}Sourcesg_cull_mode
The face-culling mode, this is used in the sg_pipeline_desc.cull_mode member when creating a pipeline object.
The default cull mode is SG_CULLMODE_NONE
D3d11_Buffer_Info
D3d11_Buffer_Info :: struct {
buf: rawptr,
}SourceBackend-specific structs and functions, these may come in handy for mixing sokol-gfx rendering with 'native backend' rendering functions.
This group of functions will be expanded as needed.
D3d11_Desc
D3d11_Desc :: struct {
shader_debugging: bool,
}SourceD3d11_Environment
D3d11_Environment :: struct {
device: rawptr,
device_context: rawptr,
}SourceD3d11_Image_Info
D3d11_Image_Info :: struct {
tex2d: rawptr,
tex3d: rawptr,
res: rawptr,
}SourceD3d11_Pipeline_Info
D3d11_Pipeline_Info :: struct {
il: rawptr,
rs: rawptr,
dss: rawptr,
bs: rawptr,
}SourceD3d11_Sampler_Info
D3d11_Sampler_Info :: struct {
smp: rawptr,
}SourceD3d11_Shader_Info
D3d11_Shader_Info :: struct {
cbufs: [8]rawptr,
vs: rawptr,
fs: rawptr,
}SourceD3d11_Swapchain
D3d11_Swapchain :: struct {
render_view: rawptr,
resolve_view: rawptr,
depth_stencil_view: rawptr,
}SourceD3d11_View_Info
D3d11_View_Info :: struct {
srv: rawptr,
uav: rawptr,
rtv: rawptr,
dsv: rawptr,
}SourceDepth_Attachment_Action
Depth_Attachment_Action :: struct {
load_action: Load_Action,
store_action: Store_Action,
clear_value: f32,
}SourceDepth_State
Depth_State :: struct {
pixel_format: Pixel_Format,
compare: Compare_Func,
write_enabled: bool,
bias: f32,
bias_slope_scale: f32,
bias_clamp: f32,
}SourceDesc
Desc :: struct {
_: u32,
buffer_pool_size: c.int,
image_pool_size: c.int,
sampler_pool_size: c.int,
shader_pool_size: c.int,
pipeline_pool_size: c.int,
view_pool_size: c.int,
uniform_buffer_size: c.int,
max_commit_listeners: c.int,
disable_validation: bool,
enforce_portable_limits: bool,
d3d11: D3d11_Desc,
metal: Metal_Desc,
wgpu: Wgpu_Desc,
vulkan: Vulkan_Desc,
allocator: Allocator,
logger: Logger,
environment: Environment,
_: u32,
}SourceEnvironment
Environment :: struct {
defaults: Environment_Defaults,
metal: Metal_Environment,
d3d11: D3d11_Environment,
wgpu: Wgpu_Environment,
vulkan: Vulkan_Environment,
}SourceEnvironment_Defaults
Environment_Defaults :: struct {
color_format: Pixel_Format,
depth_format: Pixel_Format,
sample_count: c.int,
}Sourcesg_desc
The sg_desc struct contains configuration values for sokol_gfx, it is used as parameter to the sg_setup() call.
The default configuration is:
.buffer_pool_size 128 .image_pool_size 128 .sampler_pool_size 64 .shader_pool_size 32 .pipeline_pool_size 64 .view_pool_size 256 .uniform_buffer_size 4 MB (410241024) .max_commit_listeners 1024 .disable_validation false .metal.force_managed_storage_mode false .metal.use_command_buffer_with_retained_references false .wgpu.disable_bindgroups_cache false .wgpu.bindgroups_cache_size 1024 .vulkan.copy_staging_buffer_size 4 MB .vulkan.stream_staging_buffer_size 16 MB .vulkan.descriptor_buffer_size 16 MB
.allocator.alloc_fn 0 (in this case, malloc() will be called) .allocator.free_fn 0 (in this case, free() will be called) .allocator.user_data 0
.environment.defaults.color_format: default value depends on selected backend: all GL backends: SG_PIXELFORMAT_RGBA8 Metal and D3D11: SG_PIXELFORMAT_BGRA8 WebGPU: no default (must be queried from WebGPU swapchain object) .environment.defaults.depth_format: SG_PIXELFORMAT_DEPTH_STENCIL .environment.defaults.sample_count: 1
Metal specific: (NOTE: All Objective-C object references are transferred through a bridged cast (__bridge const void*) to sokol_gfx, which will use an unretained bridged cast (__bridge id<xxx>) to retrieve the Objective-C references back. Since the bridge cast is unretained, the caller must hold a strong reference to the Objective-C object until sg_setup() returns.
.metal.force_managed_storage_mode when enabled, Metal buffers and texture resources are created in managed storage mode, otherwise sokol-gfx will decide whether to create buffers and textures in managed or shared storage mode (this is mainly a debugging option) .metal.use_command_buffer_with_retained_references when true, the sokol-gfx Metal backend will use Metal command buffers which bump the reference count of resource objects as long as they are inflight, this is slower than the default command-buffer-with-unretained-references method, this may be a workaround when confronted with lifetime validation errors from the Metal validation layer until a proper fix has been implemented .environment.metal.device a pointer to the MTLDevice object
D3D11 specific: .environment.d3d11.device a pointer to the ID3D11Device object, this must have been created before sg_setup() is called .environment.d3d11.device_context a pointer to the ID3D11DeviceContext object .d3d11.shader_debugging set this to true to compile shaders which are provided as HLSL source code with debug information and without optimization, this allows shader debugging in tools like RenderDoc, to output source code instead of byte code from sokol-shdc, omit the --binary cmdline option
WebGPU specific: .wgpu.disable_bindgroups_cache When this is true, the WebGPU backend will create and immediately release a BindGroup object in the sg_apply_bindings() call, only use this for debugging purposes. .wgpu.bindgroups_cache_size The size of the bindgroups cache for re-using BindGroup objects between sg_apply_bindings() calls. The smaller the cache size, the more likely are cache slot collisions which will cause a BindGroups object to be destroyed and a new one created. Use the information returned by sg_query_stats() to check if this is a frequent occurrence, and increase the cache size as needed (the default is 1024). NOTE: wgpu_bindgroups_cache_size must be a power-of-2 number! .environment.wgpu.device a WGPUDevice handle
Vulkan specific: .vulkan.copy_staging_buffer_size Size of the staging buffer in bytes for uploading the initial content of buffers and images, and for updating .usage.dynamic_update resources. The default is 4 MB, bigger resource updates are split into multiple chunks of the staging buffer size .vulkan.stream_staging_buffer_size Size of the staging buffer in bytes for updating .usage.stream_update resources. The default is 16 MB. The size must be big enough to accomodate all update into .usage.stream_update resources. Any additional data will cause an error log message and incomplete rendering. Note that the actually allocated size will be twice as much because the stream-staging-buffer is double-buffered. .vulkan.descriptor_buffer_size Size of the descriptor-upload buffer in bytes. The default size is 16 bytes. The size must be big enough to accomodate all unifrom-block, view- and sampler-bindings in a single frame (assume a worst-case of 256 bytes per binding). Note that the actually allocated size will be twice as much because the descriptor-buffer is double-buffered.
When using sokol_gfx.h and sokol_app.h together, consider using the helper function sglue_environment() in the sokol_glue.h header to initialize the sg_desc.environment nested struct. sglue_environment() returns a completely initialized sg_environment struct with information provided by sokol_app.h.
Face_Winding
Face_Winding :: enum i32 {
DEFAULT = 0,
CCW = 1,
CW = 2,
}Sourcesg_face_winding
The vertex-winding rule that determines a front-facing primitive. This is used in the member sg_pipeline_desc.face_winding when creating a pipeline object.
The default winding is SG_FACEWINDING_CW (clockwise)
Features
Features :: struct {
origin_top_left: bool,
image_clamp_to_border: bool,
mrt_independent_blend_state: bool,
mrt_independent_write_mask: bool,
compute: bool,
msaa_texture_bindings: bool,
separate_buffer_types: bool,
draw_base_vertex: bool,
draw_base_instance: bool,
dual_source_blending: bool,
vertexformat_int10_n2: bool,
gl_texture_views: bool,
}SourceRuntime information about available optional features, returned by sg_query_features()
Filter
Filter :: enum i32 {
DEFAULT = 0,
NEAREST = 1,
LINEAR = 2,
}Sourcesg_filter
The filtering mode when sampling a texture image. This is used in the sg_sampler_desc.min_filter, sg_sampler_desc.mag_filter and sg_sampler_desc.mipmap_filter members when creating a sampler object.
For the default is SG_FILTER_NEAREST.
Frame_Resource_Stats
Frame_Resource_Stats :: struct {
allocated: u32,
deallocated: u32,
inited: u32,
uninited: u32,
}SourceFrame_Stats
Frame_Stats :: struct {
frame_index: u32,
num_passes: u32,
num_apply_viewport: u32,
num_apply_scissor_rect: u32,
num_apply_pipeline: u32,
num_apply_bindings: u32,
num_apply_uniforms: u32,
num_draw: u32,
num_draw_ex: u32,
num_dispatch: u32,
num_update_buffer: u32,
num_append_buffer: u32,
num_update_image: u32,
num_write_buffer_unsealed: u32,
num_write_image_unsealed: u32,
num_seal_buffer: u32,
num_seal_image: u32,
size_apply_uniforms: u32,
size_update_buffer: u32,
size_append_buffer: u32,
size_update_image: u32,
buffers: Frame_Resource_Stats,
images: Frame_Resource_Stats,
samplers: Frame_Resource_Stats,
views: Frame_Resource_Stats,
shaders: Frame_Resource_Stats,
pipelines: Frame_Resource_Stats,
gl: Frame_Stats_Gl,
d3d11: Frame_Stats_D3d11,
metal: Frame_Stats_Metal,
wgpu: Frame_Stats_Wgpu,
vk: Frame_Stats_Vk,
}SourceFrame_Stats_D3d11
Frame_Stats_D3d11 :: struct {
pass: Frame_Stats_D3d11_Pass,
pipeline: Frame_Stats_D3d11_Pipeline,
bindings: Frame_Stats_D3d11_Bindings,
uniforms: Frame_Stats_D3d11_Uniforms,
draw: Frame_Stats_D3d11_Draw,
num_map: u32,
num_unmap: u32,
}SourceFrame_Stats_D3d11_Bindings
Frame_Stats_D3d11_Bindings :: struct {
num_ia_set_vertex_buffers: u32,
num_ia_set_index_buffer: u32,
num_vs_set_shader_resources: u32,
num_vs_set_samplers: u32,
num_ps_set_shader_resources: u32,
num_ps_set_samplers: u32,
num_cs_set_shader_resources: u32,
num_cs_set_samplers: u32,
num_cs_set_unordered_access_views: u32,
}SourceFrame_Stats_D3d11_Draw
Frame_Stats_D3d11_Draw :: struct {
num_draw_indexed_instanced: u32,
num_draw_indexed: u32,
num_draw_instanced: u32,
num_draw: u32,
}SourceFrame_Stats_D3d11_Pass
Frame_Stats_D3d11_Pass :: struct {
num_om_set_render_targets: u32,
num_clear_render_target_view: u32,
num_clear_depth_stencil_view: u32,
num_resolve_subresource: u32,
}SourceFrame_Stats_D3d11_Pipeline
Frame_Stats_D3d11_Pipeline :: struct {
num_rs_set_state: u32,
num_om_set_depth_stencil_state: u32,
num_om_set_blend_state: u32,
num_ia_set_primitive_topology: u32,
num_ia_set_input_layout: u32,
num_vs_set_shader: u32,
num_vs_set_constant_buffers: u32,
num_ps_set_shader: u32,
num_ps_set_constant_buffers: u32,
num_cs_set_shader: u32,
num_cs_set_constant_buffers: u32,
}SourceFrame_Stats_D3d11_Uniforms
Frame_Stats_D3d11_Uniforms :: struct {
num_update_subresource: u32,
}SourceFrame_Stats_Gl
Frame_Stats_Gl :: struct {
num_bind_buffer: u32,
num_active_texture: u32,
num_bind_texture: u32,
num_bind_sampler: u32,
num_bind_image_texture: u32,
num_use_program: u32,
num_render_state: u32,
num_vertex_attrib_pointer: u32,
num_vertex_attrib_divisor: u32,
num_enable_vertex_attrib_array: u32,
num_disable_vertex_attrib_array: u32,
num_uniform: u32,
num_memory_barriers: u32,
}Sourcesg_stats
Allows to track generic and backend-specific rendering stats, obtained via sg_query_stats().
Frame_Stats_Metal
Frame_Stats_Metal :: struct {
idpool: Frame_Stats_Metal_Idpool,
pipeline: Frame_Stats_Metal_Pipeline,
bindings: Frame_Stats_Metal_Bindings,
uniforms: Frame_Stats_Metal_Uniforms,
}SourceFrame_Stats_Metal_Bindings
Frame_Stats_Metal_Bindings :: struct {
num_set_vertex_buffer: u32,
num_set_vertex_buffer_offset: u32,
num_skip_redundant_vertex_buffer: u32,
num_set_vertex_texture: u32,
num_skip_redundant_vertex_texture: u32,
num_set_vertex_sampler_state: u32,
num_skip_redundant_vertex_sampler_state: u32,
num_set_fragment_buffer: u32,
num_set_fragment_buffer_offset: u32,
num_skip_redundant_fragment_buffer: u32,
num_set_fragment_texture: u32,
num_skip_redundant_fragment_texture: u32,
num_set_fragment_sampler_state: u32,
num_skip_redundant_fragment_sampler_state: u32,
num_set_compute_buffer: u32,
num_set_compute_buffer_offset: u32,
num_skip_redundant_compute_buffer: u32,
num_set_compute_texture: u32,
num_skip_redundant_compute_texture: u32,
num_set_compute_sampler_state: u32,
num_skip_redundant_compute_sampler_state: u32,
}SourceFrame_Stats_Metal_Idpool
Frame_Stats_Metal_Idpool :: struct {
num_added: u32,
num_released: u32,
num_garbage_collected: u32,
}SourceFrame_Stats_Metal_Pipeline
Frame_Stats_Metal_Pipeline :: struct {
num_set_blend_color: u32,
num_set_cull_mode: u32,
num_set_front_facing_winding: u32,
num_set_stencil_reference_value: u32,
num_set_depth_bias: u32,
num_set_render_pipeline_state: u32,
num_set_depth_stencil_state: u32,
}SourceFrame_Stats_Metal_Uniforms
Frame_Stats_Metal_Uniforms :: struct {
num_set_vertex_buffer_offset: u32,
num_set_fragment_buffer_offset: u32,
num_set_compute_buffer_offset: u32,
}SourceFrame_Stats_Vk
Frame_Stats_Vk :: struct {
num_cmd_pipeline_barrier: u32,
num_allocate_memory: u32,
num_free_memory: u32,
size_allocate_memory: u32,
num_delete_queue_added: u32,
num_delete_queue_collected: u32,
num_cmd_copy_buffer: u32,
num_cmd_copy_buffer_to_image: u32,
num_cmd_set_descriptor_buffer_offsets: u32,
size_descriptor_buffer_writes: u32,
}SourceFrame_Stats_Wgpu
Frame_Stats_Wgpu :: struct {
uniforms: Frame_Stats_Wgpu_Uniforms,
bindings: Frame_Stats_Wgpu_Bindings,
}SourceFrame_Stats_Wgpu_Bindings
Frame_Stats_Wgpu_Bindings :: struct {
num_set_vertex_buffer: u32,
num_skip_redundant_vertex_buffer: u32,
num_set_index_buffer: u32,
num_skip_redundant_index_buffer: u32,
num_create_bindgroup: u32,
num_discard_bindgroup: u32,
num_set_bindgroup: u32,
num_skip_redundant_bindgroup: u32,
num_bindgroup_cache_hits: u32,
num_bindgroup_cache_misses: u32,
num_bindgroup_cache_collisions: u32,
num_bindgroup_cache_invalidates: u32,
num_bindgroup_cache_hash_vs_key_mismatch: u32,
}SourceFrame_Stats_Wgpu_Uniforms
Frame_Stats_Wgpu_Uniforms :: struct {
num_set_bindgroup: u32,
size_write_buffer: u32,
}SourceGl_Buffer_Info
Gl_Buffer_Info :: struct {
buf: [2]u32,
active_slot: c.int,
}SourceGl_Image_Info
Gl_Image_Info :: struct {
tex: [2]u32,
tex_target: u32,
active_slot: c.int,
}SourceGl_Sampler_Info
Gl_Sampler_Info :: struct {
smp: u32,
}SourceGl_Shader_Info
Gl_Shader_Info :: struct {
prog: u32,
}SourceGl_Swapchain
Gl_Swapchain :: struct {
framebuffer: u32,
}SourceGl_View_Info
Gl_View_Info :: struct {
tex_view: [2]u32,
msaa_render_buffer: u32,
msaa_resolve_frame_buffer: u32,
}SourceGlsl_Shader_Uniform
Glsl_Shader_Uniform :: struct {
type: Uniform_Type,
array_count: u16,
glsl_name: cstring,
}SourceImage
Image :: struct {
id: u32,
}SourceImage_Data
Image_Data :: struct {
mip_levels: [16]Range,
}Sourcesg_image_data
Defines the content of an image through an array of sg_range structs, each range pointing to the pixel data for one mip-level. For array-, cubemap- and 3D-images each mip-level contains all slice-surfaces for that mip-level in a single tightly packed memory block.
The size of a single surface in a mip-level for a regular 2D texture can be computed via:
sg_query_surface_pitch(pixel_format, mip_width, mip_height, 1);
For array- and 3d-images the size of a single miplevel is:
num_slices * sg_query_surface_pitch(pixel_format, mip_width, mip_height, 1);
For cubemap-images the size of a single mip-level is:
6 * sg_query_surface_pitch(pixel_format, mip_width, mip_height, 1);
The order of cubemap-faces is in a mip-level data chunk is:
[0] => +X [1] => -X [2] => +Y [3] => -Y [4] => +Z [5] => -Z
NOTE: for more flexible resource initialization of immutable images also consider the sg_write_image_unsealed() function!
Image_Desc
Image_Desc :: struct {
_: u32,
type: Image_Type,
usage: Image_Usage,
width: c.int,
height: c.int,
num_slices: c.int,
num_mipmaps: c.int,
pixel_format: Pixel_Format,
sample_count: c.int,
data: Image_Data,
label: cstring,
gl_textures: [2]u32,
gl_texture_target: u32,
mtl_textures: [2]rawptr,
d3d11_texture: rawptr,
wgpu_texture: rawptr,
_: u32,
}Sourcesg_image_desc
Creation parameters for sg_image objects, used in the sg_make_image() call.
The default configuration is:
.type SG_IMAGETYPE_2D .usage .immutable = true .width 0 (must be set to >0) .height 0 (must be set to >0) .num_slices 1 (3D textures: depth; array textures: number of layers) .num_mipmaps 1 .pixel_format SG_PIXELFORMAT_RGBA8 for textures, or sg_desc.environment.defaults.color_format for render targets .sample_count 1 for textures, or sg_desc.environment.defaults.sample_count for render targets .data an sg_image_data struct to define the initial content .label 0 (optional string label for trace hooks)
Q: Why is the default sample_count for render targets identical with the "default sample count" from sg_desc.environment.defaults.sample_count?
A: So that it matches the default sample count in pipeline objects. Even though it is a bit strange/confusing that offscreen render targets by default get the same sample count as 'default swapchains', but it's better that an offscreen render target created with default parameters matches a pipeline object created with default parameters.
NOTE:
Regular images used as texture binding with usage.immutable must be fully initialized by providing a valid .data member which points to initialization data.
Images with usage._attachment or usage.storage_image must not* be created with initial content. Be aware that the initial content of pass attachment and storage images is undefined (not guaranteed to be zeroed).
ADVANCED TOPIC: Injecting native 3D-API textures:
The following struct members allow to inject your own GL, Metal or D3D11 textures into sokol_gfx:
.gl_textures[SG_NUM_INFLIGHT_FRAMES] .mtl_textures[SG_NUM_INFLIGHT_FRAMES] .d3d11_texture .wgpu_texture
For GL, you can also specify the texture target or leave it empty to use the default texture target for the image type (GL_TEXTURE_2D for SG_IMAGETYPE_2D etc)
The same rules apply as for injecting native buffers (see sg_buffer_desc documentation for more details).
Image_Extent
Image_Extent :: struct {
width: c.int,
height: c.int,
num_slices: c.int,
}Sourcesg_image_extent
Defines the size of a region within an image's mip level.
Image_Info
Image_Info :: struct {
slot: Slot_Info,
upd_frame_index: u32,
num_slots: c.int,
active_slot: c.int,
}SourceImage_Location
Image_Location :: struct {
image: Image,
mip_level: c.int,
x: c.int,
y: c.int,
slice: c.int,
}Sourcesg_image_location
Describes a source or destination location in an image.
Image_Sample_Type
Image_Sample_Type :: enum i32 {
DEFAULT = 0,
FLOAT = 1,
DEPTH = 2,
SINT = 3,
UINT = 4,
UNFILTERABLE_FLOAT = 5,
}Sourcesg_image_sample_type
The basic data type of a texture sample as expected by a shader. Must be provided in sg_shader_image and used by the validation layer in sg_apply_bindings() to check if the provided image object is compatible with what the shader expects. Apart from the sokol-gfx validation layer, WebGPU is the only backend API which actually requires matching texture and sampler type to be provided upfront for validation (other 3D APIs treat texture/sampler type mismatches as undefined behaviour).
NOTE that the following texture pixel formats require the use of SG_IMAGESAMPLETYPE_UNFILTERABLE_FLOAT, combined with a sampler of type SG_SAMPLERTYPE_NONFILTERING:
- SG_PIXELFORMAT_R32F
- SG_PIXELFORMAT_RG32F
- SG_PIXELFORMAT_RGBA32F
(when using sokol-shdc, also check out the meta tags @image_sample_type and @sampler_type)
Image_Type
Image_Type :: enum i32 {
DEFAULT = 0,
_2D = 1,
CUBE = 2,
_3D = 3,
ARRAY = 4,
}Sourcesg_image_type
Indicates the basic type of an image object (2D-texture, cubemap, 3D-texture or 2D-array-texture). Used in the sg_image_desc.type member when creating an image, and in sg_shader_image_desc to describe a sampled texture in the shader (both must match and will be checked in the validation layer when calling sg_apply_bindings).
The default image type when creating an image is SG_IMAGETYPE_2D.
Image_Usage
Image_Usage :: struct {
storage_image: bool,
color_attachment: bool,
resolve_attachment: bool,
depth_stencil_attachment: bool,
immutable: bool,
dynamic_update: bool,
stream_update: bool,
write_unsealed: bool,
}Sourcesg_image_usage
Describes the intended usage of an image object:
.storage_image (default: false) the image can be used as parent resource of a storage-image-view, which allows compute shaders to write to the image in a compute pass (for read-only access in compute shaders bind the image via a texture view instead .color_attachment (default: false) the image can be used as parent resource of a color-attachment-view, which is then passed into sg_begin_pass via sg_pass.attachments.colors[] so that fragment shaders can render into the image .resolve_attachment (default: false) the image can be used as parent resource of a resolve-attachment-view, which is then passed into sg_begin_pass via sg_pass.attachments.resolves[] as target for an MSAA-resolve operation in sg_end_pass() .depth_stencil_attachment (default: false) the image can be used as parent resource of a depth-stencil-attachmnet-view which is then passes into sg_begin_pass via sg_pass.attachments.depth_stencil as depth-stencil-buffer .immutable (default: true) the image content cannot be updated from the CPU side (but may be updated by the GPU in a render- or compute-pass) .dynamic_update (default: false) the image content is updated infrequently by the CPU via sg_update_image() .stream_update (default: false) the image content is updated each frame by the CPU via sg_update_image() .write_unsealed (default: false) when true, creates an immutable image in 'unsealed' resource state, unsealed images can be populated with data by one or multiple sg_write_image_unsealed() calls before being 'sealed' by calling sg_seal_image() which transitions from 'unsealed' to 'valid' resource state
Note that creating a texture view from the image to be used for texture-sampling in vertex-, fragment- or compute-shaders is always implicitly allowed.
Image_View_Desc
Image_View_Desc :: struct {
image: Image,
mip_level: c.int,
slice: c.int,
}SourceIndex_Type
Index_Type :: enum i32 {
DEFAULT = 0,
NONE = 1,
UINT16 = 2,
UINT32 = 3,
}Sourcesg_index_type
Indicates whether indexed rendering (fetching vertex-indices from an index buffer) is used, and if yes, the index data type (16- or 32-bits).
This is used in the sg_pipeline_desc.index_type member when creating a pipeline object.
The default index type is SG_INDEXTYPE_NONE.
Limits
Limits :: struct {
max_image_size_2d: c.int,
max_image_size_cube: c.int,
max_image_size_3d: c.int,
max_image_size_array: c.int,
max_image_array_layers: c.int,
max_vertex_attrs: c.int,
max_color_attachments: c.int,
max_texture_bindings_per_stage: c.int,
max_storage_buffer_bindings_per_stage: c.int,
max_storage_image_bindings_per_stage: c.int,
gl_max_vertex_uniform_components: c.int,
gl_max_combined_texture_image_units: c.int,
d3d11_max_unordered_access_views: c.int,
vk_min_uniform_buffer_offset_alignment: c.int,
}SourceRuntime information about resource limits, returned by sg_query_limit()
Load_Action
Load_Action :: enum i32 {
DEFAULT = 0,
CLEAR = 1,
LOAD = 2,
DONTCARE = 3,
}Sourcesg_load_action
Defines the load action that should be performed at the start of a render pass:
SG_LOADACTION_CLEAR: clear the render target SG_LOADACTION_LOAD: load the previous content of the render target SG_LOADACTION_DONTCARE: leave the render target in an undefined state
This is used in the sg_pass_action structure.
The default load action for all pass attachments is SG_LOADACTION_CLEAR, with the values rgba = { 0.5f, 0.5f, 0.5f, 1.0f }, depth=1.0f and stencil=0.
If you want to override the default behaviour, it is important to not only set the clear color, but the 'action' field as well (as long as this is _SG_LOADACTION_DEFAULT, the value fields will be ignored).
Log_Item
Log_Item :: enum i32 {
OK = 0,
MALLOC_FAILED = 1,
GL_TEXTURE_FORMAT_NOT_SUPPORTED = 2,
GL_3D_TEXTURES_NOT_SUPPORTED = 3,
GL_ARRAY_TEXTURES_NOT_SUPPORTED = 4,
GL_STORAGEBUFFER_GLSL_BINDING_OUT_OF_RANGE = 5,
GL_STORAGEIMAGE_GLSL_BINDING_OUT_OF_RANGE = 6,
GL_SHADER_COMPILATION_FAILED = 7,
GL_SHADER_LINKING_FAILED = 8,
GL_VERTEX_ATTRIBUTE_NOT_FOUND_IN_SHADER = 9,
GL_UNIFORMBLOCK_NAME_NOT_FOUND_IN_SHADER = 10,
GL_IMAGE_SAMPLER_NAME_NOT_FOUND_IN_SHADER = 11,
GL_FRAMEBUFFER_STATUS_UNDEFINED = 12,
GL_FRAMEBUFFER_STATUS_INCOMPLETE_ATTACHMENT = 13,
GL_FRAMEBUFFER_STATUS_INCOMPLETE_MISSING_ATTACHMENT = 14,
GL_FRAMEBUFFER_STATUS_UNSUPPORTED = 15,
GL_FRAMEBUFFER_STATUS_INCOMPLETE_MULTISAMPLE = 16,
GL_FRAMEBUFFER_STATUS_UNKNOWN = 17,
D3D11_FEATURE_LEVEL_0_DETECTED = 18,
D3D11_CREATE_BUFFER_FAILED = 19,
D3D11_CREATE_BUFFER_SRV_FAILED = 20,
D3D11_CREATE_BUFFER_UAV_FAILED = 21,
D3D11_CREATE_DEPTH_TEXTURE_UNSUPPORTED_PIXEL_FORMAT = 22,
D3D11_CREATE_DEPTH_TEXTURE_FAILED = 23,
D3D11_CREATE_2D_TEXTURE_UNSUPPORTED_PIXEL_FORMAT = 24,
D3D11_CREATE_2D_TEXTURE_FAILED = 25,
D3D11_CREATE_2D_SRV_FAILED = 26,
D3D11_CREATE_3D_TEXTURE_UNSUPPORTED_PIXEL_FORMAT = 27,
D3D11_CREATE_3D_TEXTURE_FAILED = 28,
D3D11_CREATE_3D_SRV_FAILED = 29,
D3D11_CREATE_MSAA_TEXTURE_FAILED = 30,
D3D11_CREATE_SAMPLER_STATE_FAILED = 31,
D3D11_UNIFORMBLOCK_HLSL_REGISTER_B_OUT_OF_RANGE = 32,
D3D11_STORAGEBUFFER_HLSL_REGISTER_T_OUT_OF_RANGE = 33,
D3D11_STORAGEBUFFER_HLSL_REGISTER_U_OUT_OF_RANGE = 34,
D3D11_IMAGE_HLSL_REGISTER_T_OUT_OF_RANGE = 35,
D3D11_STORAGEIMAGE_HLSL_REGISTER_U_OUT_OF_RANGE = 36,
D3D11_SAMPLER_HLSL_REGISTER_S_OUT_OF_RANGE = 37,
D3D11_LOAD_D3DCOMPILER_47_DLL_FAILED = 38,
D3D11_SHADER_COMPILATION_FAILED = 39,
D3D11_SHADER_COMPILATION_OUTPUT = 40,
D3D11_CREATE_CONSTANT_BUFFER_FAILED = 41,
D3D11_CREATE_INPUT_LAYOUT_FAILED = 42,
D3D11_CREATE_RASTERIZER_STATE_FAILED = 43,
D3D11_CREATE_DEPTH_STENCIL_STATE_FAILED = 44,
D3D11_CREATE_BLEND_STATE_FAILED = 45,
D3D11_CREATE_RTV_FAILED = 46,
D3D11_CREATE_DSV_FAILED = 47,
D3D11_CREATE_UAV_FAILED = 48,
D3D11_MAP_FOR_UPDATE_BUFFER_FAILED = 49,
D3D11_MAP_FOR_APPEND_BUFFER_FAILED = 50,
D3D11_MAP_FOR_UPDATE_IMAGE_FAILED = 51,
METAL_CREATE_BUFFER_FAILED = 52,
METAL_TEXTURE_FORMAT_NOT_SUPPORTED = 53,
METAL_CREATE_TEXTURE_FAILED = 54,
METAL_CREATE_SAMPLER_FAILED = 55,
METAL_SHADER_COMPILATION_FAILED = 56,
METAL_SHADER_CREATION_FAILED = 57,
METAL_SHADER_COMPILATION_OUTPUT = 58,
METAL_SHADER_ENTRY_NOT_FOUND = 59,
METAL_UNIFORMBLOCK_MSL_BUFFER_SLOT_OUT_OF_RANGE = 60,
METAL_STORAGEBUFFER_MSL_BUFFER_SLOT_OUT_OF_RANGE = 61,
METAL_STORAGEIMAGE_MSL_TEXTURE_SLOT_OUT_OF_RANGE = 62,
METAL_IMAGE_MSL_TEXTURE_SLOT_OUT_OF_RANGE = 63,
METAL_SAMPLER_MSL_SAMPLER_SLOT_OUT_OF_RANGE = 64,
METAL_CREATE_CPS_FAILED = 65,
METAL_CREATE_CPS_OUTPUT = 66,
METAL_CREATE_RPS_FAILED = 67,
METAL_CREATE_RPS_OUTPUT = 68,
METAL_CREATE_DSS_FAILED = 69,
WGPU_BINDGROUPS_POOL_EXHAUSTED = 70,
WGPU_BINDGROUPSCACHE_SIZE_GREATER_ONE = 71,
WGPU_BINDGROUPSCACHE_SIZE_POW2 = 72,
WGPU_CREATEBINDGROUP_FAILED = 73,
WGPU_CREATE_BUFFER_FAILED = 74,
WGPU_CREATE_TEXTURE_FAILED = 75,
WGPU_CREATE_TEXTURE_VIEW_FAILED = 76,
WGPU_CREATE_SAMPLER_FAILED = 77,
WGPU_CREATE_SHADER_MODULE_FAILED = 78,
WGPU_SHADER_CREATE_BINDGROUP_LAYOUT_FAILED = 79,
WGPU_UNIFORMBLOCK_WGSL_GROUP0_BINDING_OUT_OF_RANGE = 80,
WGPU_TEXTURE_WGSL_GROUP1_BINDING_OUT_OF_RANGE = 81,
WGPU_STORAGEBUFFER_WGSL_GROUP1_BINDING_OUT_OF_RANGE = 82,
WGPU_STORAGEIMAGE_WGSL_GROUP1_BINDING_OUT_OF_RANGE = 83,
WGPU_SAMPLER_WGSL_GROUP1_BINDING_OUT_OF_RANGE = 84,
WGPU_CREATE_PIPELINE_LAYOUT_FAILED = 85,
WGPU_CREATE_RENDER_PIPELINE_FAILED = 86,
WGPU_CREATE_COMPUTE_PIPELINE_FAILED = 87,
VULKAN_REQUIRED_EXTENSION_FUNCTION_MISSING = 88,
VULKAN_ALLOC_DEVICE_MEMORY_NO_SUITABLE_MEMORY_TYPE = 89,
VULKAN_ALLOCATE_MEMORY_FAILED = 90,
VULKAN_ALLOC_BUFFER_DEVICE_MEMORY_FAILED = 91,
VULKAN_ALLOC_IMAGE_DEVICE_MEMORY_FAILED = 92,
VULKAN_DELETE_QUEUE_EXHAUSTED = 93,
VULKAN_STAGING_CREATE_BUFFER_FAILED = 94,
VULKAN_STAGING_ALLOCATE_MEMORY_FAILED = 95,
VULKAN_STAGING_BIND_BUFFER_MEMORY_FAILED = 96,
VULKAN_STAGING_STREAM_BUFFER_OVERFLOW = 97,
VULKAN_STAGING_IMAGE_ROW_PITCH_GREATER_STAGING_BUFFER = 98,
VULKAN_CREATE_SHARED_BUFFER_FAILED = 99,
VULKAN_ALLOCATE_SHARED_BUFFER_MEMORY_FAILED = 100,
VULKAN_BIND_SHARED_BUFFER_MEMORY_FAILED = 101,
VULKAN_MAP_SHARED_BUFFER_MEMORY_FAILED = 102,
VULKAN_CREATE_BUFFER_FAILED = 103,
VULKAN_BIND_BUFFER_MEMORY_FAILED = 104,
VULKAN_CREATE_IMAGE_FAILED = 105,
VULKAN_BIND_IMAGE_MEMORY_FAILED = 106,
VULKAN_CREATE_SHADER_MODULE_FAILED = 107,
VULKAN_UNIFORMBLOCK_SPIRV_SET0_BINDING_OUT_OF_RANGE = 108,
VULKAN_TEXTURE_SPIRV_SET1_BINDING_OUT_OF_RANGE = 109,
VULKAN_STORAGEBUFFER_SPIRV_SET1_BINDING_OUT_OF_RANGE = 110,
VULKAN_STORAGEIMAGE_SPIRV_SET1_BINDING_OUT_OF_RANGE = 111,
VULKAN_SAMPLER_SPIRV_SET1_BINDING_OUT_OF_RANGE = 112,
VULKAN_CREATE_DESCRIPTOR_SET_LAYOUT_FAILED = 113,
VULKAN_SHADER_UNIFORM_DESCRIPTOR_SET_SIZE_VS_CACHE_SIZE = 114,
VULKAN_CREATE_PIPELINE_LAYOUT_FAILED = 115,
VULKAN_CREATE_GRAPHICS_PIPELINE_FAILED = 116,
VULKAN_CREATE_COMPUTE_PIPELINE_FAILED = 117,
VULKAN_CREATE_IMAGE_VIEW_FAILED = 118,
VULKAN_VIEW_MAX_DESCRIPTOR_SIZE = 119,
VULKAN_CREATE_SAMPLER_FAILED = 120,
VULKAN_SAMPLER_MAX_DESCRIPTOR_SIZE = 121,
VULKAN_WAIT_FOR_FENCE_FAILED = 122,
VULKAN_UNIFORM_BUFFER_OVERFLOW = 123,
VULKAN_DESCRIPTOR_BUFFER_OVERFLOW = 124,
IDENTICAL_COMMIT_LISTENER = 125,
COMMIT_LISTENER_ARRAY_FULL = 126,
TRACE_HOOKS_NOT_ENABLED = 127,
DEALLOC_BUFFER_INVALID_STATE = 128,
DEALLOC_IMAGE_INVALID_STATE = 129,
DEALLOC_SAMPLER_INVALID_STATE = 130,
DEALLOC_SHADER_INVALID_STATE = 131,
DEALLOC_PIPELINE_INVALID_STATE = 132,
DEALLOC_VIEW_INVALID_STATE = 133,
INIT_BUFFER_INVALID_STATE = 134,
INIT_IMAGE_INVALID_STATE = 135,
INIT_SAMPLER_INVALID_STATE = 136,
INIT_SHADER_INVALID_STATE = 137,
INIT_PIPELINE_INVALID_STATE = 138,
INIT_VIEW_INVALID_STATE = 139,
UNINIT_BUFFER_INVALID_STATE = 140,
UNINIT_IMAGE_INVALID_STATE = 141,
UNINIT_SAMPLER_INVALID_STATE = 142,
UNINIT_SHADER_INVALID_STATE = 143,
UNINIT_PIPELINE_INVALID_STATE = 144,
UNINIT_VIEW_INVALID_STATE = 145,
FAIL_BUFFER_INVALID_STATE = 146,
FAIL_IMAGE_INVALID_STATE = 147,
FAIL_SAMPLER_INVALID_STATE = 148,
FAIL_SHADER_INVALID_STATE = 149,
FAIL_PIPELINE_INVALID_STATE = 150,
FAIL_VIEW_INVALID_STATE = 151,
BUFFER_POOL_EXHAUSTED = 152,
IMAGE_POOL_EXHAUSTED = 153,
SAMPLER_POOL_EXHAUSTED = 154,
SHADER_POOL_EXHAUSTED = 155,
PIPELINE_POOL_EXHAUSTED = 156,
VIEW_POOL_EXHAUSTED = 157,
BEGINPASS_TOO_MANY_COLOR_ATTACHMENTS = 158,
BEGINPASS_TOO_MANY_RESOLVE_ATTACHMENTS = 159,
BEGINPASS_ATTACHMENTS_ALIVE = 160,
DRAW_WITHOUT_BINDINGS = 161,
WRITE_BUFFER_UNSEALED_BUFFER_ALIVE = 162,
WRITE_IMAGE_UNSEALED_IMAGE_ALIVE = 163,
SEAL_BUFFER_ALIVE = 164,
SEAL_IMAGE_ALIVE = 165,
SHADERDESC_TOO_MANY_VERTEXSTAGE_TEXTURES = 166,
SHADERDESC_TOO_MANY_FRAGMENTSTAGE_TEXTURES = 167,
SHADERDESC_TOO_MANY_COMPUTESTAGE_TEXTURES = 168,
SHADERDESC_TOO_MANY_VERTEXSTAGE_STORAGEBUFFERS = 169,
SHADERDESC_TOO_MANY_FRAGMENTSTAGE_STORAGEBUFFERS = 170,
SHADERDESC_TOO_MANY_COMPUTESTAGE_STORAGEBUFFERS = 171,
SHADERDESC_TOO_MANY_VERTEXSTAGE_STORAGEIMAGES = 172,
SHADERDESC_TOO_MANY_FRAGMENTSTAGE_STORAGEIMAGES = 173,
SHADERDESC_TOO_MANY_COMPUTESTAGE_STORAGEIMAGES = 174,
SHADERDESC_TOO_MANY_VERTEXSTAGE_TEXTURESAMPLERPAIRS = 175,
SHADERDESC_TOO_MANY_FRAGMENTSTAGE_TEXTURESAMPLERPAIRS = 176,
SHADERDESC_TOO_MANY_COMPUTESTAGE_TEXTURESAMPLERPAIRS = 177,
VALIDATE_BUFFERDESC_CANARY = 178,
VALIDATE_BUFFERDESC_IMMUTABLE_DYNAMIC_STREAM = 179,
VALIDATE_BUFFERDESC_UNSEALED_VS_IMMUTABLE = 180,
VALIDATE_BUFFERDESC_SEPARATE_BUFFER_TYPES = 181,
VALIDATE_BUFFERDESC_EXPECT_NONZERO_SIZE = 182,
VALIDATE_BUFFERDESC_EXPECT_MATCHING_DATA_SIZE = 183,
VALIDATE_BUFFERDESC_EXPECT_ZERO_DATA_SIZE = 184,
VALIDATE_BUFFERDESC_EXPECT_NO_DATA = 185,
VALIDATE_BUFFERDESC_EXPECT_DATA = 186,
VALIDATE_BUFFERDESC_STORAGEBUFFER_SUPPORTED = 187,
VALIDATE_BUFFERDESC_STORAGEBUFFER_SIZE_MULTIPLE_4 = 188,
VALIDATE_IMAGEDATA_NODATA = 189,
VALIDATE_IMAGEDATA_DATA_SIZE = 190,
VALIDATE_IMAGEDESC_CANARY = 191,
VALIDATE_IMAGEDESC_IMMUTABLE_DYNAMIC_STREAM = 192,
VALIDATE_IMAGEDESC_UNSEALED_VS_IMMUTABLE = 193,
VALIDATE_IMAGEDESC_UNSEALED_VS_ATTACHMENT = 194,
VALIDATE_IMAGEDESC_ATTACHMENT_COLOR_DEPTH_STENCIL = 195,
VALIDATE_IMAGEDESC_IMAGETYPE_2D_NUMSLICES = 196,
VALIDATE_IMAGEDESC_IMAGETYPE_CUBE_NUMSLICES = 197,
VALIDATE_IMAGEDESC_IMAGE [truncated]SourceLogger
Logger :: struct {
func: proc(
a0: cstring,
a1: u32,
a2: u32,
a3: cstring,
a4: u32,
a5: cstring,
a6: rawptr,
),
a0: cstring,
a1: u32,
a2: u32,
a3: cstring,
a4: u32,
a5: cstring,
a6: rawptr,
user_data: rawptr,
}Sourcesg_logger
Used in sg_desc to provide a logging function. Please be aware that without logging function, sokol-gfx will be completely silent, e.g. it will not report errors, warnings and validation layer messages. For maximum error verbosity, compile in debug mode (e.g. NDEBUG not defined) and provide a compatible logger function in the sg_setup() call (for instance the standard logging function from sokol_log.h).
Metal_Desc
Metal_Desc :: struct {
force_managed_storage_mode: bool,
use_command_buffer_with_retained_references: bool,
}SourceMetal_Environment
Metal_Environment :: struct {
device: rawptr,
}SourceMetal_Swapchain
Metal_Swapchain :: struct {
current_drawable: rawptr,
depth_stencil_texture: rawptr,
msaa_color_texture: rawptr,
}Sourcesg_swapchain
Used in sg_begin_pass() to provide details about an external swapchain (pixel formats, sample count and backend-API specific render surface objects).
The following information must be provided:
- the width and height of the swapchain surfaces in number of pixels,
- the pixel format of the render- and optional msaa-resolve-surface
- the pixel format of the optional depth- or depth-stencil-surface
- the MSAA sample count for the render and depth-stencil surface
If the pixel formats and MSAA sample counts are left zero-initialized, their defaults are taken from the sg_environment struct provided in the sg_setup() call.
The width and height must be > 0.
The boolean sg_swapchain.invalid is used to communicate an invalid swapchain state to sokol-gfx (for instance the swapchain code outside of sokol-gfx not being able to create swapchain surfaces). When the .invalid boolean is set to true, all other sg_swapchain struct items must be zeroed (checked in the validation layer), and all rendering in this swapchain-pass will be silently skipped.
For valid swapchains, the following backend API specific objects must be passed in as 'type erased' void pointers:
GL:
- on all GL backends, a GL framebuffer object must be provided. This
can be zero for the default framebuffer.
D3D11:
- an ID3D11RenderTargetView for the rendering surface, without
MSAA rendering this surface will also be displayed
- an optional ID3D11DepthStencilView for the depth- or depth/stencil
buffer surface
- when MSAA rendering is used, another ID3D11RenderTargetView
which serves as MSAA resolve target and will be displayed
WebGPU (same as D3D11, except different types)
- a WGPUTextureView for the rendering surface, without
MSAA rendering this surface will also be displayed
- an optional WGPUTextureView for the depth- or depth/stencil
buffer surface
- when MSAA rendering is used, another WGPUTextureView
which serves as MSAA resolve target and will be displayed
Metal (NOTE that the roles of provided surfaces is slightly different than on D3D11 or WebGPU in case of MSAA vs non-MSAA rendering):
- A current CAMetalDrawable (NOT an MTLDrawable!) which will be presented.
This will either be rendered to directly (if no MSAA is used), or serve as MSAA-resolve target.
- an optional MTLTexture for the depth- or depth-stencil buffer
- an optional multisampled MTLTexture which serves as intermediate
rendering surface which will then be resolved into the CAMetalDrawable.
NOTE that for Metal you must use an ObjC __bridge cast to properly tunnel the ObjC object id through a C void*, e.g.:
swapchain.metal.current_drawable = (__bridge const void*) [mtkView currentDrawable];
On all other backends you shouldn't need to mess with the reference count.
It's a good practice to write a helper function which returns an initialized sg_swapchain struct, which can then be plugged directly into sg_pass.swapchain. Look at the function sglue_swapchain() in the sokol_glue.h as an example.
Mtl_Buffer_Info
Mtl_Buffer_Info :: struct {
buf: [2]rawptr,
active_slot: c.int,
}SourceMtl_Image_Info
Mtl_Image_Info :: struct {
tex: [2]rawptr,
active_slot: c.int,
}SourceMtl_Pipeline_Info
Mtl_Pipeline_Info :: struct {
rps: rawptr,
dss: rawptr,
}SourceMtl_Sampler_Info
Mtl_Sampler_Info :: struct {
smp: rawptr,
}SourceMtl_Shader_Info
Mtl_Shader_Info :: struct {
vertex_lib: rawptr,
fragment_lib: rawptr,
vertex_func: rawptr,
fragment_func: rawptr,
}SourceMtl_Shader_Threads_Per_Threadgroup
Mtl_Shader_Threads_Per_Threadgroup :: struct {
x: c.int,
y: c.int,
z: c.int,
}SourcePass
Pass :: struct {
_: u32,
compute: bool,
action: Pass_Action,
attachments: Attachments,
swapchain: Swapchain,
label: cstring,
_: u32,
}Sourcesg_pass
The sg_pass structure is passed as argument into the sg_begin_pass() function.
For a swapchain render pass, provide an sg_pass_action and sg_swapchain struct (for instance via the sglue_swapchain() helper function from sokol_glue.h):
sg_begin_pass(&(sg_pass){ .action = { ... }, .swapchain = sglue_swapchain(), });
For an offscreen render pass, provide an sg_pass_action struct with attachment view objects:
sg_begin_pass(&(sg_pass){ .action = { ... }, .attachments = { .colors = { ... }, .resolves = { ... }, .depth_stencil = ..., }, });
You can also omit the .action object to get default pass action behaviour (clear to color=grey, depth=1 and stencil=0).
For a compute pass, just set the sg_pass.compute boolean to true:
sg_begin_pass(&(sg_pass){ .compute = true });
Pass_Action
Pass_Action :: struct {
colors: [8]Color_Attachment_Action,
depth: Depth_Attachment_Action,
stencil: Stencil_Attachment_Action,
}SourcePipeline
Pipeline :: struct {
id: u32,
}SourcePipeline_Desc
Pipeline_Desc :: struct {
_: u32,
compute: bool,
shader: Shader,
layout: Vertex_Layout_State,
depth: Depth_State,
stencil: Stencil_State,
color_count: c.int,
colors: [8]Color_Target_State,
primitive_type: Primitive_Type,
index_type: Index_Type,
cull_mode: Cull_Mode,
face_winding: Face_Winding,
sample_count: c.int,
blend_color: Color,
alpha_to_coverage_enabled: bool,
label: cstring,
_: u32,
}SourcePipeline_Info
Pipeline_Info :: struct {
slot: Slot_Info,
}SourcePixel_Format
Pixel_Format :: enum i32 {
DEFAULT = 0,
NONE = 1,
R8 = 2,
R8SN = 3,
R8UI = 4,
R8SI = 5,
R16 = 6,
R16SN = 7,
R16UI = 8,
R16SI = 9,
R16F = 10,
RG8 = 11,
RG8SN = 12,
RG8UI = 13,
RG8SI = 14,
R32UI = 15,
R32SI = 16,
R32F = 17,
RG16 = 18,
RG16SN = 19,
RG16UI = 20,
RG16SI = 21,
RG16F = 22,
RGBA8 = 23,
SRGB8A8 = 24,
RGBA8SN = 25,
RGBA8UI = 26,
RGBA8SI = 27,
BGRA8 = 28,
SBGR8A8 = 29,
RGB10A2 = 30,
RG11B10F = 31,
RGB9E5 = 32,
RG32UI = 33,
RG32SI = 34,
RG32F = 35,
RGBA16 = 36,
RGBA16SN = 37,
RGBA16UI = 38,
RGBA16SI = 39,
RGBA16F = 40,
RGBA32UI = 41,
RGBA32SI = 42,
RGBA32F = 43,
DEPTH = 44,
DEPTH_STENCIL = 45,
BC1_RGBA = 46,
BC2_RGBA = 47,
BC3_RGBA = 48,
BC3_SRGBA = 49,
BC4_R = 50,
BC4_RSN = 51,
BC5_RG = 52,
BC5_RGSN = 53,
BC6H_RGBF = 54,
BC6H_RGBUF = 55,
BC7_RGBA = 56,
BC7_SRGBA = 57,
ETC2_RGB8 = 58,
ETC2_SRGB8 = 59,
ETC2_RGB8A1 = 60,
ETC2_RGBA8 = 61,
ETC2_SRGB8A8 = 62,
EAC_R11 = 63,
EAC_R11SN = 64,
EAC_RG11 = 65,
EAC_RG11SN = 66,
ASTC_4x4_RGBA = 67,
ASTC_4x4_SRGBA = 68,
}Sourcesg_pixel_format
sokol_gfx.h basically uses the same pixel formats as WebGPU, since these are supported on most newer GPUs.
A pixelformat name consist of three parts:
- components (R, RG, RGB or RGBA)
- bit width per component (8, 16 or 32)
- component data type:
- unsigned normalized (no postfix)
- signed normalized (SN postfix)
- unsigned integer (UI postfix)
- signed integer (SI postfix)
- float (F postfix)
Not all pixel formats can be used for everything, call sg_query_pixelformat() to inspect the capabilities of a given pixelformat. The function returns an sg_pixelformat_info struct with the following members:
- sample: the pixelformat can be sampled as texture at least with
nearest filtering
- filter: the pixelformat can be sampled as texture with linear
filtering
- render: the pixelformat can be used as render-pass attachment
- blend: blending is supported when used as render-pass attachment
- msaa: multisample-antialiasing is supported when used
as render-pass attachment
- depth: the pixelformat can be used for depth-stencil attachments
- compressed: this is a block-compressed format
- bytes_per_pixel: the numbers of bytes in a pixel (0 for compressed formats)
The default pixel format for texture images is SG_PIXELFORMAT_RGBA8.
The default pixel format for render target images is platform-dependent and taken from the sg_environment struct passed into sg_setup(). Typically the default formats are:
- for the Metal, D3D11 and WebGPU backends: SG_PIXELFORMAT_BGRA8
- for GL backends: SG_PIXELFORMAT_RGBA8
Pixelformat_Info
Pixelformat_Info :: struct {
sample: bool,
filter: bool,
render: bool,
blend: bool,
msaa: bool,
depth: bool,
compressed: bool,
read: bool,
write: bool,
bytes_per_pixel: c.int,
}SourceRuntime information about a pixel format, returned by sg_query_pixelformat().
Primitive_Type
Primitive_Type :: enum i32 {
DEFAULT = 0,
POINTS = 1,
LINES = 2,
LINE_STRIP = 3,
TRIANGLES = 4,
TRIANGLE_STRIP = 5,
}Sourcesg_primitive_type
This is the common subset of 3D primitive types supported across all 3D APIs. This is used in the sg_pipeline_desc.primitive_type member when creating a pipeline object.
The default primitive type is SG_PRIMITIVETYPE_TRIANGLES.
Range
Range :: struct {
ptr: rawptr,
size: c.size_t,
}Sourcesg_range is a pointer-size-pair struct used to pass memory blobs into sokol-gfx. When initialized from a value type (array or struct), you can use the SG_RANGE() macro to build an sg_range struct. For functions which take either a sg_range pointer, or a (C++) sg_range reference, use the SG_RANGE_REF macro as a solution which compiles both in C and C++.
Resource_State
Resource_State :: enum i32 {
INITIAL = 0,
ALLOC = 1,
UNSEALED = 2,
VALID = 3,
FAILED = 4,
INVALID = 5,
}Sourcesg_resource_state
The current state of a resource in its resource pool. Resources start in the INITIAL state, which means the pool slot is unoccupied and can be allocated. When a resource is created, first an id is allocated, and the resource pool slot is set to state ALLOC. After allocation, the resource is initialized, which may result in the VALID, UNSEALED or FAILED state. UNSEALED is a special state for immutable buffers and images which allows to write data into the resource after the creation call. The reason why allocation and initialization are separate is because some resource types (e.g. buffers and images) might be asynchronously initialized by the user application. If a resource which is not in the VALID state is attempted to be used for rendering, rendering operations will silently be dropped.
The special INVALID state is returned in sg_query_xxx_state() if no resource object exists for the provided resource id.
Sampler
Sampler :: struct {
id: u32,
}SourceSampler_Desc
Sampler_Desc :: struct {
_: u32,
min_filter: Filter,
mag_filter: Filter,
mipmap_filter: Filter,
wrap_u: Wrap,
wrap_v: Wrap,
wrap_w: Wrap,
min_lod: f32,
max_lod: f32,
border_color: Border_Color,
compare: Compare_Func,
max_anisotropy: u32,
label: cstring,
gl_sampler: u32,
mtl_sampler: rawptr,
d3d11_sampler: rawptr,
wgpu_sampler: rawptr,
_: u32,
}Sourcesg_sampler_desc
Creation parameters for sg_sampler objects, used in the sg_make_sampler() call
.min_filter: SG_FILTER_NEAREST .mag_filter: SG_FILTER_NEAREST .mipmap_filter SG_FILTER_NEAREST .wrap_u: SG_WRAP_REPEAT .wrap_v: SG_WRAP_REPEAT .wrap_w: SG_WRAP_REPEAT (only SG_IMAGETYPE_3D) .min_lod 0.0f .max_lod FLT_MAX .border_color SG_BORDERCOLOR_OPAQUE_BLACK .compare SG_COMPAREFUNC_NEVER .max_anisotropy 1 (must be 1..16)
Sampler_Info
Sampler_Info :: struct {
slot: Slot_Info,
}SourceSampler_Type
Sampler_Type :: enum i32 {
DEFAULT = 0,
FILTERING = 1,
NONFILTERING = 2,
COMPARISON = 3,
}Sourcesg_sampler_type
The basic type of a texture sampler (sampling vs comparison) as defined in a shader. Must be provided in sg_shader_sampler_desc.
sg_image_sample_type and sg_sampler_type for a texture/sampler pair must be compatible with each other, specifically only the following pairs are allowed:
- SG_IMAGESAMPLETYPE_FLOAT => (SG_SAMPLERTYPE_FILTERING or SG_SAMPLERTYPE_NONFILTERING)
- SG_IMAGESAMPLETYPE_UNFILTERABLE_FLOAT => SG_SAMPLERTYPE_NONFILTERING
- SG_IMAGESAMPLETYPE_SINT => SG_SAMPLERTYPE_NONFILTERING
- SG_IMAGESAMPLETYPE_UINT => SG_SAMPLERTYPE_NONFILTERING
- SG_IMAGESAMPLETYPE_DEPTH => SG_SAMPLERTYPE_COMPARISON
Shader
Shader :: struct {
id: u32,
}SourceShader_Attr_Base_Type
Shader_Attr_Base_Type :: enum i32 {
UNDEFINED = 0,
FLOAT = 1,
SINT = 2,
UINT = 3,
}SourceShader_Desc
Shader_Desc :: struct {
_: u32,
vertex_func: Shader_Function,
fragment_func: Shader_Function,
compute_func: Shader_Function,
attrs: [16]Shader_Vertex_Attr,
uniform_blocks: [8]Shader_Uniform_Block,
views: [32]Shader_View,
samplers: [12]Shader_Sampler,
texture_sampler_pairs: [32]Shader_Texture_Sampler_Pair,
mtl_threads_per_threadgroup: Mtl_Shader_Threads_Per_Threadgroup,
label: cstring,
_: u32,
}SourceShader_Function
Shader_Function :: struct {
source: cstring,
bytecode: Range,
entry: cstring,
d3d11_target: cstring,
d3d11_filepath: cstring,
}SourceShader_Info
Shader_Info :: struct {
slot: Slot_Info,
}SourceShader_Sampler
Shader_Sampler :: struct {
stage: Shader_Stage,
sampler_type: Sampler_Type,
hlsl_register_s_n: u8,
msl_sampler_n: u8,
wgsl_group1_binding_n: u8,
spirv_set1_binding_n: u8,
}SourceShader_Stage
Shader_Stage :: enum i32 {
NONE = 0,
VERTEX = 1,
FRAGMENT = 2,
COMPUTE = 3,
}Sourcesg_shader_desc
Used as parameter of sg_make_shader() to create a shader object which communicates shader source or bytecode and shader interface reflection information to sokol-gfx.
If you use sokol-shdc you can ignore the following information since the sg_shader_desc struct will be code-generated.
Otherwise you need to provide the following information to the sg_make_shader() call:
- a vertex- and fragment-shader function:
- the shader source or bytecode
- an optional entry point name
- for D3D11: an optional compile target when source code is provided
(the defaults are "vs_4_0" and "ps_4_0")
- ...or alternatively, a compute function:
- the shader source or bytecode
- an optional entry point name
- for D3D11: an optional compile target when source code is provided
(the default is "cs_5_0")
- vertex attributes required by some backends (not for compute shaders):
- the vertex attribute base type (undefined, float, signed int, unsigned int),
this information is only used in the validation layer to check that the pipeline object vertex formats are compatible with the input vertex attribute type used in the vertex shader. NOTE that the default base type 'undefined' skips the validation layer check.
- for the GL backend: optional vertex attribute names used for name lookup
- for the D3D11 backend: semantic names and indices
- only for compute shaders on the Metal backend:
- the workgroup size aka 'threads per thread-group'
In other 3D APIs this is declared in the shader code:
- GLSL:
layout(local_size_x=x, local_size_y=y, local_size_y=z) in; - HLSL:
[numthreads(x, y, z)] - WGSL:
@workgroup_size(x, y, z)
...but in Metal the workgroup size is declared on the CPU side
- reflection information for each uniform block binding used by the shader:
- the shader stage the uniform block appears in (SG_SHADERSTAGE_*)
- the size in bytes of the uniform block
- backend-specific bindslots:
- HLSL: the constant buffer register
register(b0..7) - MSL: the buffer attribute
[[buffer(0..7)]] - WGSL: the binding in
@group(0) @binding(0..15) - GLSL only: a description of the uniform block interior
- the memory layout standard (SG_UNIFORMLAYOUT_*)
- for each member in the uniform block:
- the member type (SG_UNIFORM_*)
- if the member is an array, the array count
- the member name
- reflection information for each texture-, storage-buffer and
storage-image bindings by the shader, each with an associated view type:
- texture bindings => texture views
- storage-buffer bindings => storage-buffer views
- storage-image bindings => storage-image views
- texture bindings must provide the following information:
- the shader stage the texture binding appears in (SG_SHADERSTAGE_*)
- the image type (SG_IMAGETYPE_*)
- the image-sample type (SG_IMAGESAMPLETYPE_*)
- whether the texture is multisampled
- backend specific bindslots:
- HLSL: the texture register
register(t0..31) - MSL: the texture attribute
[[texture(0..31)]] - WGSL: the binding in
@group(1) @binding(0..127)
- storage-buffer bindings must provide the following information:
- the shader stage the storage buffer appears in (SG_SHADERSTAGE_*)
- whether the storage buffer is readonly
- backend specific bindslots:
- HLSL:
- for storage buffer bindings:
register(t0..31) - for read/write storage buffer bindings:
register(u0..31) - MSL: the buffer attribute
[[buffer(8..23)]] - WGSL: the binding in
@group(1) @binding(0..127) - GL: the binding in
layout(binding=0..sg_limits.max_storage_buffer_bindings_per_stage)
- storage-image bindings must provide the following information:
- the shader stage (must be SG_SHADERSTAGE_COMPUTE)
- whether the storage image is writeonly or readwrite (for readonly
access use a regular texture binding instead)
- the image type expected by the shader (SG_IMAGETYPE_*)
- the access pixel format expected by the shader (SG_PIXELFORMAT_*),
note that only a subset of pixel formats is allowed for storage image bindings
- backend specific bindslots:
- HLSL: the UAV register
register(u0..31) - MSL: the texture attribute
[[texture(0..31)]] - WGSL: the binding in
@group(1) @binding(0..127) - GLSL: the binding in
layout(binding=0..sg_imits.max_storage_buffer_bindings_per_stage, [access_format])
- reflection information for each sampler used by the shader:
- the shader stage the sampler appears in (SG_SHADERSTAGE_*)
- the sampler type (SG_SAMPLERTYPE_*)
- backend specific bindslots:
- HLSL: the sampler register
register(s0..11) - MSL: the sampler attribute
[[sampler(0..11)]] - WGSL: the binding in
@group(0) @binding(0..127)
- reflection information for each texture-sampler pair used by
the shader:
- the shader stage (SG_SHADERSTAGE_*)
- the texture's array index in the sg_shader_desc.views[] array
- the sampler's array index in the sg_shader_desc.samplers[] array
- GLSL only: the name of the combined image-sampler object
The number and order of items in the sg_shader_desc.attrs[] array corresponds to the items in sg_pipeline_desc.layout.attrs.
- sg_shader_desc.attrs[N] => sg_pipeline_desc.layout.attrs[N]
NOTE that vertex attribute indices currently cannot have gaps.
The items index in the sg_shader_desc.uniform_blocks[] array corresponds to the ub_slot arg in sg_apply_uniforms():
- sg_shader_desc.uniform_blocks[N] => sg_apply_uniforms(N, ...)
The items in the sg_shader_desc.views[] array directly map to the views in the sg_bindings.views[] array!
For all GL backends, shader source-code must be provided. For D3D11 and Metal, either shader source-code or byte-code can be provided.
NOTE that the uniform-block, view and sampler arrays may have gaps. This allows to use the same sg_bindings struct for different but related shader variations.
For D3D11, if source code is provided, the d3dcompiler_47.dll will be loaded on demand. If this fails, shader creation will fail. When compiling HLSL source code, you can provide an optional target string via sg_shader_stage_desc.d3d11_target, the default target is "vs_4_0" for the vertex shader stage and "ps_4_0" for the pixel shader stage. You may optionally provide the file path to enable the default #include handler behavior when compiling source code.
Shader_Storage_Buffer_View
Shader_Storage_Buffer_View :: struct {
stage: Shader_Stage,
readonly: bool,
hlsl_register_t_n: u8,
hlsl_register_u_n: u8,
msl_buffer_n: u8,
wgsl_group1_binding_n: u8,
spirv_set1_binding_n: u8,
glsl_binding_n: u8,
}SourceShader_Storage_Image_View
Shader_Storage_Image_View :: struct {
stage: Shader_Stage,
image_type: Image_Type,
access_format: Pixel_Format,
writeonly: bool,
hlsl_register_u_n: u8,
msl_texture_n: u8,
wgsl_group1_binding_n: u8,
spirv_set1_binding_n: u8,
glsl_binding_n: u8,
}SourceShader_Texture_Sampler_Pair
Shader_Texture_Sampler_Pair :: struct {
stage: Shader_Stage,
view_slot: u8,
sampler_slot: u8,
glsl_name: cstring,
}SourceShader_Texture_View
Shader_Texture_View :: struct {
stage: Shader_Stage,
image_type: Image_Type,
sample_type: Image_Sample_Type,
multisampled: bool,
hlsl_register_t_n: u8,
msl_texture_n: u8,
wgsl_group1_binding_n: u8,
spirv_set1_binding_n: u8,
}SourceShader_Uniform_Block
Shader_Uniform_Block :: struct {
stage: Shader_Stage,
size: u32,
hlsl_register_b_n: u8,
msl_buffer_n: u8,
wgsl_group0_binding_n: u8,
spirv_set0_binding_n: u8,
layout: Uniform_Layout,
glsl_uniforms: [16]Glsl_Shader_Uniform,
}SourceShader_Vertex_Attr
Shader_Vertex_Attr :: struct {
base_type: Shader_Attr_Base_Type,
glsl_name: cstring,
hlsl_sem_name: cstring,
hlsl_sem_index: u8,
}SourceShader_View
Shader_View :: struct {
texture: Shader_Texture_View,
storage_buffer: Shader_Storage_Buffer_View,
storage_image: Shader_Storage_Image_View,
}SourceSlot_Info
Slot_Info :: struct {
state: Resource_State,
res_id: u32,
uninit_count: u32,
}Sourcesg_buffer_info sg_image_info sg_sampler_info sg_shader_info sg_pipeline_info sg_view_info
These structs contain various internal resource attributes which might be useful for debug-inspection. Please don't rely on the actual content of those structs too much, as they are quite closely tied to sokol_gfx.h internals and may change more frequently than the other public API elements.
The *_info structs are used as the return values of the following functions:
sg_query_buffer_info() sg_query_image_info() sg_query_sampler_info() sg_query_shader_info() sg_query_pipeline_info() sg_query_view_info()
Stats
Stats :: struct {
prev_frame: Frame_Stats,
cur_frame: Frame_Stats,
total: Total_Stats,
}SourceStencil_Attachment_Action
Stencil_Attachment_Action :: struct {
load_action: Load_Action,
store_action: Store_Action,
clear_value: u8,
}SourceStencil_Face_State
Stencil_Face_State :: struct {
compare: Compare_Func,
fail_op: Stencil_Op,
depth_fail_op: Stencil_Op,
pass_op: Stencil_Op,
}SourceStencil_Op
Stencil_Op :: enum i32 {
DEFAULT = 0,
KEEP = 1,
ZERO = 2,
REPLACE = 3,
INCR_CLAMP = 4,
DECR_CLAMP = 5,
INVERT = 6,
INCR_WRAP = 7,
DECR_WRAP = 8,
}Sourcesg_stencil_op
The operation performed on a currently stored stencil-value when a comparison test passes or fails. This is used when creating a pipeline object in the following sg_pipeline_desc struct items:
sg_pipeline_desc .stencil .front .fail_op .depth_fail_op .pass_op .back .fail_op .depth_fail_op .pass_op
The default value is SG_STENCILOP_KEEP.
Stencil_State
Stencil_State :: struct {
enabled: bool,
front: Stencil_Face_State,
back: Stencil_Face_State,
read_mask: u8,
write_mask: u8,
ref: u8,
}SourceStore_Action
Store_Action :: enum i32 {
DEFAULT = 0,
STORE = 1,
DONTCARE = 2,
}Sourcesg_store_action
Defines the store action that should be performed at the end of a render pass:
SG_STOREACTION_STORE: store the rendered content to the color attachment image SG_STOREACTION_DONTCARE: allows the GPU to discard the rendered content
Swapchain
Swapchain :: struct {
invalid: bool,
width: c.int,
height: c.int,
sample_count: c.int,
color_format: Pixel_Format,
depth_format: Pixel_Format,
metal: Metal_Swapchain,
d3d11: D3d11_Swapchain,
wgpu: Wgpu_Swapchain,
vulkan: Vulkan_Swapchain,
gl: Gl_Swapchain,
}SourceTexture_View_Desc
Texture_View_Desc :: struct {
image: Image,
mip_levels: Texture_View_Range,
slices: Texture_View_Range,
}SourceTexture_View_Range
Texture_View_Range :: struct {
base: c.int,
count: c.int,
}SourceTotal_Resource_Stats
Total_Resource_Stats :: struct {
alive: u32,
free: u32,
allocated: u32,
deallocated: u32,
inited: u32,
uninited: u32,
}SourceTotal_Stats
Total_Stats :: struct {
buffers: Total_Resource_Stats,
images: Total_Resource_Stats,
samplers: Total_Resource_Stats,
views: Total_Resource_Stats,
shaders: Total_Resource_Stats,
pipelines: Total_Resource_Stats,
}SourceUniform_Layout
Uniform_Layout :: enum i32 {
DEFAULT = 0,
NATIVE = 1,
STD140 = 2,
}Sourcesg_uniform_layout
A hint for the interior memory layout of uniform blocks. This is only relevant for the GL backend where the internal layout of uniform blocks must be known to sokol-gfx. For all other backends the internal memory layout of uniform blocks doesn't matter, sokol-gfx will just pass uniform data as an opaque memory blob to the 3D backend.
SG_UNIFORMLAYOUT_NATIVE (default) Native layout means that a 'backend-native' memory layout is used. For the GL backend this means that uniforms are packed tightly in memory (e.g. there are no padding bytes).
SG_UNIFORMLAYOUT_STD140 The memory layout is a subset of std140. Arrays are only allowed for the FLOAT4, INT4 and MAT4. Alignment is as is as follows:
FLOAT, INT: 4 byte alignment FLOAT2, INT2: 8 byte alignment FLOAT3, INT3: 16 byte alignment(!) FLOAT4, INT4: 16 byte alignment MAT4: 16 byte alignment FLOAT4[], INT4[]: 16 byte alignment
The overall size of the uniform block must be a multiple of 16.
For more information search for 'UNIFORM DATA LAYOUT' in the documentation block at the start of the header.
Uniform_Type
Uniform_Type :: enum i32 {
INVALID = 0,
FLOAT = 1,
FLOAT2 = 2,
FLOAT3 = 3,
FLOAT4 = 4,
INT = 5,
INT2 = 6,
INT3 = 7,
INT4 = 8,
MAT4 = 9,
}Sourcesg_uniform_type
The data type of a uniform block member. This is used to describe the internal layout of uniform blocks when creating a shader object. This is only required for the GL backend, all other backends will ignore the interior layout of uniform blocks.
Vertex_Attr_State
Vertex_Attr_State :: struct {
buffer_index: c.int,
offset: c.int,
format: Vertex_Format,
}SourceVertex_Buffer_Layout_State
Vertex_Buffer_Layout_State :: struct {
stride: c.int,
step_func: Vertex_Step,
step_rate: c.int,
}Sourcesg_pipeline_desc
The sg_pipeline_desc struct defines all creation parameters for an sg_pipeline object, used as argument to the sg_make_pipeline() function:
Pipeline objects come in two flavours:
- render pipelines for use in render passes
- compute pipelines for use in compute passes
A compute pipeline only requires a compute shader object but no 'render state', while a render pipeline requires a vertex/fragment shader object and additional render state declarations:
- the vertex layout for all input vertex buffers
- a shader object
- the 3D primitive type (points, lines, triangles, ...)
- the index type (none, 16- or 32-bit)
- all the fixed-function-pipeline state (depth-, stencil-, blend-state, etc...)
If the vertex data has no gaps between vertex components, you can omit the .layout.buffers[].stride and layout.attrs[].offset items (leave them default-initialized to 0), sokol-gfx will then compute the offsets and strides from the vertex component formats (.layout.attrs[].format). Please note that ALL vertex attribute offsets must be 0 in order for the automatic offset computation to kick in.
Note that if you use vertex-pulling from storage buffers instead of fixed-function vertex input you can simply omit the entire nested .layout struct.
The default configuration is as follows:
.compute: false (must be set to true for a compute pipeline) .shader: 0 (must be initialized with a valid sg_shader id!) .layout: .buffers[]: vertex buffer layouts .stride: 0 (if no stride is given it will be computed) .step_func SG_VERTEXSTEP_PER_VERTEX .step_rate 1 .attrs[]: vertex attribute declarations .buffer_index 0 the vertex buffer bind slot .offset 0 (offsets can be omitted if the vertex layout has no gaps) .format SG_VERTEXFORMAT_INVALID (must be initialized!) .depth: .pixel_format: sg_desc.context.depth_format .compare: SG_COMPAREFUNC_ALWAYS .write_enabled: false .bias: 0.0f .bias_slope_scale: 0.0f .bias_clamp: 0.0f .stencil: .enabled: false .front/back: .compare: SG_COMPAREFUNC_ALWAYS .fail_op: SG_STENCILOP_KEEP .depth_fail_op: SG_STENCILOP_KEEP .pass_op: SG_STENCILOP_KEEP .read_mask: 0 .write_mask: 0 .ref: 0 .color_count 1 .colors[0..color_count] .pixel_format sg_desc.context.color_format .write_mask: SG_COLORMASK_RGBA .blend: .enabled: false .src_factor_rgb: SG_BLENDFACTOR_ONE .dst_factor_rgb: SG_BLENDFACTOR_ZERO .op_rgb: SG_BLENDOP_ADD .src_factor_alpha: SG_BLENDFACTOR_ONE .dst_factor_alpha: SG_BLENDFACTOR_ZERO .op_alpha: SG_BLENDOP_ADD .primitive_type: SG_PRIMITIVETYPE_TRIANGLES .index_type: SG_INDEXTYPE_NONE .cull_mode: SG_CULLMODE_NONE .face_winding: SG_FACEWINDING_CW .sample_count: sg_desc.context.sample_count .blend_color: (sg_color) { 0.0f, 0.0f, 0.0f, 0.0f } .alpha_to_coverage_enabled: false .label 0 (optional string label for trace hooks)
Vertex_Format
Vertex_Format :: enum i32 {
INVALID = 0,
FLOAT = 1,
FLOAT2 = 2,
FLOAT3 = 3,
FLOAT4 = 4,
INT = 5,
INT2 = 6,
INT3 = 7,
INT4 = 8,
UINT = 9,
UINT2 = 10,
UINT3 = 11,
UINT4 = 12,
BYTE4 = 13,
BYTE4N = 14,
UBYTE4 = 15,
UBYTE4N = 16,
SHORT2 = 17,
SHORT2N = 18,
USHORT2 = 19,
USHORT2N = 20,
SHORT4 = 21,
SHORT4N = 22,
USHORT4 = 23,
USHORT4N = 24,
INT10_N2 = 25,
UINT10_N2 = 26,
HALF2 = 27,
HALF4 = 28,
}Sourcesg_vertex_format
The data type of a vertex component. This is used to describe the layout of input vertex data when creating a pipeline object.
NOTE that specific mapping rules exist from the CPU-side vertex formats to the vertex attribute base type in the vertex shader code (see doc header section 'ON VERTEX FORMATS').
Vertex_Layout_State
Vertex_Layout_State :: struct {
buffers: [8]Vertex_Buffer_Layout_State,
attrs: [16]Vertex_Attr_State,
}SourceVertex_Step
Vertex_Step :: enum i32 {
DEFAULT = 0,
PER_VERTEX = 1,
PER_INSTANCE = 2,
}Sourcesg_vertex_step
Defines whether the input pointer of a vertex input stream is advanced 'per vertex' or 'per instance'. The default step-func is SG_VERTEXSTEP_PER_VERTEX. SG_VERTEXSTEP_PER_INSTANCE is used with instanced-rendering.
The vertex-step is part of the vertex-layout definition when creating pipeline objects.
View
View :: struct {
id: u32,
}SourceView_Desc
View_Desc :: struct {
_: u32,
texture: Texture_View_Desc,
storage_buffer: Buffer_View_Desc,
storage_image: Image_View_Desc,
color_attachment: Image_View_Desc,
resolve_attachment: Image_View_Desc,
depth_stencil_attachment: Image_View_Desc,
label: cstring,
_: u32,
}SourceView_Info
View_Info :: struct {
slot: Slot_Info,
}SourceView_Type
View_Type :: enum i32 {
INVALID = 0,
STORAGEBUFFER = 1,
STORAGEIMAGE = 2,
TEXTURE = 3,
COLORATTACHMENT = 4,
RESOLVEATTACHMENT = 5,
DEPTHSTENCILATTACHMENT = 6,
}Sourcesg_view_type
Allows to query the type of a view object via the function sg_query_view_type()
Vulkan_Desc
Vulkan_Desc :: struct {
copy_staging_buffer_size: c.int,
stream_staging_buffer_size: c.int,
descriptor_buffer_size: c.int,
}SourceVulkan_Environment
Vulkan_Environment :: struct {
instance: rawptr,
physical_device: rawptr,
device: rawptr,
queue: rawptr,
queue_family_index: u32,
}SourceVulkan_Swapchain
Vulkan_Swapchain :: struct {
render_image: rawptr,
render_view: rawptr,
resolve_image: rawptr,
resolve_view: rawptr,
depth_stencil_image: rawptr,
depth_stencil_view: rawptr,
render_finished_semaphore: rawptr,
present_complete_semaphore: rawptr,
}SourceWgpu_Buffer_Info
Wgpu_Buffer_Info :: struct {
buf: rawptr,
}SourceWgpu_Desc
Wgpu_Desc :: struct {
disable_bindgroups_cache: bool,
bindgroups_cache_size: c.int,
}SourceWgpu_Environment
Wgpu_Environment :: struct {
device: rawptr,
}SourceWgpu_Image_Info
Wgpu_Image_Info :: struct {
tex: rawptr,
}SourceWgpu_Pipeline_Info
Wgpu_Pipeline_Info :: struct {
render_pipeline: rawptr,
compute_pipeline: rawptr,
}SourceWgpu_Sampler_Info
Wgpu_Sampler_Info :: struct {
smp: rawptr,
}SourceWgpu_Shader_Info
Wgpu_Shader_Info :: struct {
vs_mod: rawptr,
fs_mod: rawptr,
bgl: rawptr,
}SourceWgpu_Swapchain
Wgpu_Swapchain :: struct {
render_view: rawptr,
resolve_view: rawptr,
depth_stencil_view: rawptr,
}SourceWgpu_View_Info
Wgpu_View_Info :: struct {
view: rawptr,
}SourceWrap
Wrap :: enum i32 {
DEFAULT = 0,
REPEAT = 1,
CLAMP_TO_EDGE = 2,
CLAMP_TO_BORDER = 3,
MIRRORED_REPEAT = 4,
}Sourcesg_wrap
The texture coordinates wrapping mode when sampling a texture image. This is used in the sg_image_desc.wrap_u, .wrap_v and .wrap_w members when creating an image.
The default wrap mode is SG_WRAP_REPEAT.
NOTE: SG_WRAP_CLAMP_TO_BORDER is not supported on all backends and platforms. To check for support, call sg_query_features() and check the "clamp_to_border" boolean in the returned sg_features struct.
Platforms which don't support SG_WRAP_CLAMP_TO_BORDER will silently fall back to SG_WRAP_CLAMP_TO_EDGE without a validation error.
Write_Buffer_Desc
Write_Buffer_Desc :: struct {
src: Write_Buffer_Source,
dst: Buffer_Location,
size: c.size_t,
}Sourcesg_write_buffer_desc
Describes a write operation into a buffer from CPU memory into a buffer object.
.src Defines the location of the source data in CPU memory. See documentation of the struct sg_write_buffer_source for details. .dst Defines the destination buffer object and offset into the buffer's memory. .size Number of bytes to be copied. When this is default-zero, the size will be taken from .src.data.size instead.
Write_Buffer_Source
Write_Buffer_Source :: struct {
data: Range,
offset: c.size_t,
}Sourcesg_write_buffer_source
Describes the data to be written from CPU memory into a buffer.
.data Pointer to and size of the data in CPU memory .offset Optional offset that's added to data.ptr
Write_Image_Desc
Write_Image_Desc :: struct {
src: Write_Image_Source,
dst: Image_Location,
size: Image_Extent,
}Sourcesg_write_image_desc
Describes a write operation into a single mipmap from CPU memory into an image object.
.src Defines the location and layout of the source data in CPU memory. See documentation of the struct sg_write_image_source for details. .dst Defines the destination image object and the location of the destination region to write the data to. See documentation of the struct sg_image_location for details. .size Defines the size of the destination region. See the documentation of the struct sg_image_extent for details.
Note the following rules for zero-initialized default values:
.src.bytes_per_row Default-zero indicates that the source data is layed out as a tightly packed complete mip-map (e.g. when writing data into miplevel 0 of a 256x256 RGBA8 image, .src.bytes_per_row will be 1024. .src.bytes_per_slice Same as above, default-zero indicates that the source data is layed out as a tightly packed complete mip-map (e.g. when writing data into miplevel 0 of a 256x256 image, .src.bytes_per_slice will be 256*1024). .size.width, .size.height, .size.num_slices Default-zero means 'the remaining width, height and num_slices' taking .dst.x/y/slice into account. E.g. when .dst.x/y/num_slices are all zero, .size.width/height/num_slices for instance for a 256x256 cubemap the default sizes are: .width=256, .height=256, .num_slices=6
Write_Image_Source
Write_Image_Source :: struct {
data: Range,
offset: c.size_t,
bytes_per_row: c.int,
bytes_per_slice: c.int,
}Sourcesg_write_image_source
Describes the data to be written from CPU memory into an image:
.data Pointer to and size of the data in CPU memory .offset Optional offset that's added to data.ptr .bytes_per_row Optional number of bytes between rows of image data, can be left zero-initialized when the image data is tighly packed (e.g. no gaps between rows). For uncompressed pixel formats, .bytes_per_row must be a multiple of the pixel size in bytes (e.g. for RGBA4 a multiple of 4), for compressed pixel formats, .bytes_per_row must be a multiple of the compression block size in bytes .bytes_per_slice Optional number of bytes of between the start of array/cubemap/volume slices, can be left zero-initialized when the image data is tightly packed (e.g. no gaps between slices). Must be a multiple of .bytes_per_row
Constants
19DEBUG
DEBUG :: _ = #config(SOKOL_GFX_DEBUG, SOKOL_DEBUG)SourceINVALID_ID
INVALID_ID :: 0Sourcevarious compile-time constants in the public API
MAX_COLOR_ATTACHMENTS
MAX_COLOR_ATTACHMENTS :: 8SourceMAX_MIPMAPS
MAX_MIPMAPS :: 16SourceMAX_PORTABLE_COLOR_ATTACHMENTS
MAX_PORTABLE_COLOR_ATTACHMENTS :: 4SourceMAX_PORTABLE_STORAGEBUFFER_BINDINGS_PER_STAGE
MAX_PORTABLE_STORAGEBUFFER_BINDINGS_PER_STAGE :: 8SourceMAX_PORTABLE_STORAGEIMAGE_BINDINGS_PER_STAGE
MAX_PORTABLE_STORAGEIMAGE_BINDINGS_PER_STAGE :: 4SourceMAX_PORTABLE_TEXTURE_BINDINGS_PER_STAGE
MAX_PORTABLE_TEXTURE_BINDINGS_PER_STAGE :: 16SourceMAX_SAMPLER_BINDSLOTS
MAX_SAMPLER_BINDSLOTS :: 12SourceMAX_TEXTURE_SAMPLER_PAIRS
MAX_TEXTURE_SAMPLER_PAIRS :: 32SourceMAX_UNIFORMBLOCK_BINDSLOTS
MAX_UNIFORMBLOCK_BINDSLOTS :: 8SourceMAX_UNIFORMBLOCK_MEMBERS
MAX_UNIFORMBLOCK_MEMBERS :: 16SourceMAX_VERTEXBUFFER_BINDSLOTS
MAX_VERTEXBUFFER_BINDSLOTS :: 8SourceMAX_VERTEX_ATTRIBUTES
MAX_VERTEX_ATTRIBUTES :: 16SourceMAX_VIEW_BINDSLOTS
MAX_VIEW_BINDSLOTS :: 32SourceNUM_INFLIGHT_FRAMES
NUM_INFLIGHT_FRAMES :: 2SourceSOKOL_DEBUG
SOKOL_DEBUG :: _ = #config(SOKOL_DEBUG, ODIN_DEBUG)SourceUSE_DLL
USE_DLL :: _ = #config(SOKOL_DLL, false)SourceUSE_GL
USE_GL :: _ = #config(SOKOL_USE_GL, false)Source