gfx 0.2.1

D graphics rendering library

To use this package, run the following command in your project's root directory:

Manual usage
Put the following dependency into your project's dependences section:

This package provides sub packages which can be used individually:

gfx:bindings - Foundation for bindings to C libraries

gfx:core - Gfx-d core package

gfx:decl - Declarative engine for Gfx-d

gfx:genmesh - Mesh generation routines

gfx:gl3 - OpenGL backend and bindings for Gfx-d

gfx:graal - Graphics API abstraction layer

gfx:math - Maths for Gfx-d (but not only...)

gfx:memalloc - Memory allocator for Gfx-d

gfx:vulkan - Vulkan backend and bindings for Gfx-d

gfx:window - Window utility for Gfx-d

gfx:declapi - gfx-d declapi example

gfx:deferred - gfx-d deferred example

gfx:depth - gfx-d depth example

gfx:shadow - gfx-d shadow example

gfx:stencil - gfx-d stencil example

gfx:swapchain - gfx-d swapchain example

gfx:texture - gfx-d texture example

gfx:triangle - gfx-d triangle example


Build Status Build Status

Graphics rendering engine for the D programming language.

Online API reference

The main idea is to have an abstraction layer (here named Graal - Graphics API abstraction layer) and several backends implementing it. There are several packages:

  • gfx:core: Core utilities: reference counting, logging...
  • gfx: Main package containing gfx.graal module.
  • gfx:vulkan: The Vulkan backend implementation.
  • gfx:gl3: The OpenGL3 backend implementation.
  • gfx:decl: Optional declarative engine for pipeline creation.
  • gfx:math: Optional math library.
  • gfx:memalloc: Optional memory allocator.
  • gfx:window: Optional toy window library. Used by examples.

A few examples are also available as DUB subpackages. To run an example right away, the following should do it.

$ dub fetch gfx
$ dub run gfx:triangle

Some examples need a 3rdparty library available as a submodule. To run these, you have to clone the repo:

$ git clone --recursive
$ cd gfx-d
$ dub run gfx:texture

gfx:core - Core utilies

The main utility is the reference counting, that is necessary for deterministic resource management.

import gfx.core.rc;

class SomeResource : IAtomicRefCounted

    this(/+ ... +/)
        // ...

    override void dispose()
        // ...

void fun()
    // makeRc makes Rc!SomeResource
    auto res1 = makeRc!SomeResource(/+ ... +/);
    // getResource returns SomeResource. rc turns it into Rc!SomeResource
    auto res2 = getResource().rc; // res

    // res1 and res2 are automatically released at end of scope

The good thing here is that IAtomicRefCounted is an interface, so it is possible to build completely abstract API with reference counting enabled. The implementation is provided by a one liner mixin. Another useful thing is that the counter is embedded in each object, so objects can be passed around by reference in the most natural way and still be referenced where it is needed. A smart pointer (Rc) is provided. A more traditional API is also provided (retainObj, releaseObj, ...)

Graal - Graphics API abstraction layer

One of gfx-d targets is to allow using the full power of Vulkan. Therefore Graal API is closely modeled on Vulkan to enable the use of all low-level Vulkan features. It results that Graal itself is a low level library. Ideally, a higher level API will be built one day on top of Graal.

Graal loads only SPIR-V shader programs. NDC system is the one of the backend (gfx:math is NDC agnostic and provides projection matrices for different NDCs).

gfx:vulkan - Vulkan backend

This is the Vulkan backend implementation that translates almost directly from Graal to Vulkan. This should be the preferred and natural backend when using gfx-d.

gfx:gl3 - OpenGL backend

If Vulkan is not available on a target machine, gfx:gl3 is available as backup. SPIRV-Cross is used to translate shaders to GLSL. Many shaders will be compatible for both Vulkan and OpenGL backends out of the box, but there are limitations:

  • push constants are not available
  • depth map need range adaptation There are probably many more...


Allow to setup render passes and pipelines with SDL description. (It is planned to move to Lua at some point in the future)

A pipeline SDL description look as follow:

graal:DescriptorSetLayout {
    // store is the mechanism to reference other objects
    store "dsl"
    bindings {
        0 descriptorType="uniformBufferDynamic" descriptorCount=1 stages="vertex"
        1 descriptorType="uniformBuffer" descriptorCount=1 stages="fragment"
// ...
graal:ShaderModule {
    local-store "vertSh"
    // source can also be asset or binary base64 (although that is discouraged)
    source "view:shader.vert.spv"
    entryPoint "main" // this is the default and can be omitted
graal:Pipeline {
    store "pl"
    shaders {
        // shaders can be attached from the store
        vertex "store:vertSh"
        // or created inline
        fragment source="view:shader.frag.spv" entryPoint="main" store="fragSh"
    inputBindings {
        0 stride="sizeof:Vertex" instanced=off
    inputAttribs {
        // three ways to specify input attribs
        0 binding=0 format="rgb32_sFloat" offset=0
        1 binding=0 format="formatof:Vertex.normal" offset="offsetof:Vertex.normal"
        2 binding=0 member="Vertex.color" // shortcut to formatof and offsetof
    assembly primitive="triangleList" primitiveRestart=off
    // if depthBias needed, specify it in a children of rasterizer
    rasterizer polygonMode="fill" cull="back" front="ccw" lineWidth=1 depthClamp=off {
        depthBias slope=2f const=1f
    viewports {
        // ...
    depthInfo on write=on compareOp="less"
    blendInfo {
        attachments {
            // ...
    dynamicStates "viewport" "scissor"
    layout "store:layout"
    renderPass "store:rp" subpass=0

gfx:math - Math library

  • matrices (row major)
  • vectors
  • transforms
  • projections (for different coordinate systems and depth ranges)
  • inverse matrix
  • floating point utility

gfx:memalloc - A graphics memory allocator

import gfx.core.rc : rc;
import gfx.graal.buffer : BufferUsage;
import gfx.memalloc : AllocatorOptions, AllocOptions, HeapOptions, MemoryUsage;

AllocatorOptions options;
options.heapOptions = // one HeapOption per heap in the device, specifying default block size for each

auto allocator = createAllocator(device, options).rc;

auto stagBuf = allocator.allocateBuffer(
    BufferUsage.transferSrc, size, AllocOptions.forUsage(MemoryUsage.cpuToGpu)

gfx:window - A toy windowing system

3 backends:

  • Win32
  • Xcb
  • Wayland (without decorations)
Backend[] backendLoadOrder = [
    Backend.vulkan, Backend.gl3
// Create a display for the running platform
// The instance is created by the display. Backend is chosen at runtime
// depending on detected API support. (i.e. Vulkan is preferred)
auto display = createDisplay(backendLoadOrder).rc;
// Retrieve the Graal instance that is used to list and open device(s)
auto instance = display.instance.rc;
// Create a window. The surface is created during the call to show.
auto window = display.createWindow();, 480);

  • Rémi Thebault
Sub packages:
gfx:bindings, gfx:core, gfx:decl, gfx:genmesh, gfx:gl3, gfx:graal, gfx:math, gfx:memalloc, gfx:vulkan, gfx:window, gfx:declapi, gfx:deferred, gfx:depth, gfx:shadow, gfx:stencil, gfx:swapchain, gfx:texture, gfx:triangle
0.2.1 2020-Nov-15
0.2.0 2020-Nov-15
0.1.2 2018-Dec-25
0.1.1 2018-Dec-24
0.1.0 2018-Dec-16
Show all 17 versions
Download Stats:
  • 0 downloads today

  • 0 downloads this week

  • 0 downloads this month

  • 295 downloads total

Short URL: