IDL — Interface Definition Language
bgfx uses a custom Interface Definition Language (IDL) to define its entire public API in a single
source-of-truth file: scripts/bgfx.idl. From this file, code generators produce the C99 API,
C++ API, language bindings, and documentation — ensuring that all representations stay in sync.
For additional background and motivation, see the blog post: IDL — Interface Definition Language.
Purpose
The IDL serves several goals:
Single source of truth — The API (types, functions, flags, enums, structs, handles) is declared once in
bgfx.idl. All generated outputs derive from this file.Multi-language bindings — Code generators read the IDL and produce bindings for C99, C#, D, Zig, Beef, C3, and potentially other languages.
Documentation generation — The
docs-rst.luagenerator produces reStructuredText API reference documentation from the IDL.Consistency — Changes to the API only need to be made in one place. The code generators ensure that all bindings and documentation are updated automatically.
File overview
All IDL-related files live under scripts/:
bgfx.idlThe IDL source file. Contains all type definitions, function declarations, flag/enum definitions, struct layouts, handle types, documentation comments, and the section hierarchy for the generated docs.
idl.luaThe IDL parser/runtime. Sets up the Lua environment that
bgfx.idlexecutes in. Provides the DSL keywords (typedef,enum,flag,struct,handle,func,funcptr,section,version, etc.) as Lua metatable-driven constructors.codegen.luaShared code generation utilities. Reads the parsed IDL, resolves types, converts between naming conventions (CamelCase ↔ underscore_case), and provides template expansion for function signatures.
bgfx-codegen.luaThe main code generator. Reads the IDL via
codegen.luaand produces the C99 header, C++ header, C99-to-C++ bridge implementation, and the internal function ID tables.bindings-*.luaPer-language binding generators (
bindings-cs.lua,bindings-d.lua,bindings-zig.lua,bindings-bf.lua,bindings-c3.lua). Each reads the IDL and outputs the API in the target language’s syntax and conventions.docs-rst.luaGenerates reStructuredText API reference documentation (
docs/bgfx.rst) from the IDL.
Running the code generators
The code generators are invoked via the makefile at the repository root:
make idl
This runs the Lua scripts that regenerate all C/C++ headers, language bindings, and documentation
from scripts/bgfx.idl.
IDL syntax reference
The IDL file is valid Lua, executed in a special environment that provides the DSL keywords.
Comments prefixed with --- become documentation comments attached to the next declaration.
version
Declares the API version number:
version(140)
typedef
Declares a type alias. These map IDL type names to their C/C++ equivalents:
typedef "uint32_t"
typedef "ViewId"
typedef "CallbackI" { cname = "callback_interface" }
The optional table provides attributes. cname overrides the C binding name.
handle
Declares an opaque handle type. Handles are type-safe 16-bit integers used to reference GPU resources:
handle "TextureHandle"
handle "VertexBufferHandle"
enum
Declares an enumeration. Each member can have a --- documentation comment:
enum.TextureFormat { comment = "Texture formats:", section = "Textures" }
.BC1 --- DXT1 R5G6B5A1.
.BC2 --- DXT3 R5G6B5A4.
.Unknown --- Compressed formats above.
()
The () sentinel marks the end of the enum (generates a Count member). The section
attribute controls where this type appears in the generated documentation hierarchy.
flag
Declares a bitfield flag type. Similar to enum, but members represent individual bits:
flag.StateWrite { bits = 64, base = 1, section = "State Flags", label = "Write" }
.R --- Enable R write.
.G --- Enable G write.
.B --- Enable B write.
.A --- Enable alpha write.
.Z (39) --- Enable depth write.
.Rgb { "R", "G", "B" } --- Enable RGB write.
.Mask { "Rgb", "A", "Z" } --- Write all channels mask.
Attributes:
bits— Total bit width (32 or 64).shift— Bit offset where this flag group starts.range— Number of bits in this group.base— Starting value for auto-numbering.section— Documentation section.label— Display label for documentation grouping.
A member with a number in parentheses (e.g. .Z (39)) sets an explicit bit position. Members
with a table of names (e.g. .Rgb { "R", "G", "B" }) define combined masks.
struct
Declares a data structure with typed fields:
struct.Init { ctor, section = "Initialization and Shutdown" }
.type "RendererType::Enum" --- Select rendering backend.
.vendorId "uint16_t" --- Vendor PCI ID. See: `BGFX_PCI_ID_*`.
.deviceId "uint16_t" --- Device ID.
.capabilities "uint64_t" --- Capabilities initialization mask.
.debug "bool" --- Enable device for debugging.
.profile "bool" --- Enable device for profiling.
Attributes:
ctor— Generate a constructor with default values.namespace— Nest this struct inside another (e.g.namespace = "Caps"producesCaps::Limits).section— Documentation section.
func
Declares a function. The first string is the return type, followed by named parameters:
--- Advance to next frame.
func.frame { section = "Frame" }
"uint32_t" --- Current frame number.
.flags "uint8_t" --- Frame flags.
{ default = "BGFX_FRAME_NONE" }
Attributes:
section— Documentation section.const— Mark as a const method (for class member functions).conly— Only emit in the C99 API, not in C++.cpponly— Only emit in the C++ API, not in C99.cppinline— Provide an inline C++ implementation string.
Parameters can have:
{ default = "value" }— Default argument value.{ out }— Output parameter.{ inout }— Input/output parameter.
funcptr
Declares a function pointer type:
funcptr.ReleaseFn
"void"
.ptr "void*" --- Pointer to allocated data.
.userData "void*" --- User defined data if needed.
section
Declares a documentation section for organizing the generated API reference. Sections form a hierarchy based on their level (0 = top-level heading, 1 = chapter, 2+ = subsections):
section("API Reference", 0)
section("General", 1)
section("Initialization and Shutdown", 2)
Types and functions reference their section via the section attribute. The documentation
generator (docs-rst.lua) uses the section tree to organize the output.
Documentation comments
Lines starting with --- before a declaration become documentation comments. These are emitted
as Doxygen-style comments in the C/C++ headers and as descriptions in the generated docs:
--- Render frame.
---
--- @attention `bgfx::renderFrame` is a blocking call.
---
--- @warning This call should only be used on platforms that don't
--- allow creating a separate rendering thread.
---
func.renderFrame { section = "Platform specific" }
"RenderFrame::Enum"
.msecs "int32_t"
{ default = -1 }
Supported Doxygen tags in comments: @attention, @warning, @remarks, @param,
@returns.
Adding a new API function
To add a new function to the bgfx API:
Add the function declaration in
scripts/bgfx.idlwith the appropriatesectionattribute and---documentation comments.Run
make idlto regenerate all headers, bindings, and documentation.Implement the function in
src/bgfx.cpp(and the renderer backends if needed).Verify the generated output in
include/bgfx/bgfx.h,include/bgfx/c99/bgfx.h, and the binding files underbindings/.