gfx 0.1.0

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 - Raw bindings to Gfx APIs

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:math - Maths for Gfx-d

gfx:memalloc - Memory allocator for Gfx-d

gfx:window - Window utility for Gfx-d

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

gfx:swapchain - gfx-d swapchain example

gfx:triangle - gfx-d triangle example

gfx:texture - gfx-d texture example

gfx:depth - gfx-d depth example

gfx:stencil - gfx-d stencil example

gfx:shadow - gfx-d shadow example

gfx:declapi - gfx-d declapi example

gfx-d

Graphics rendering engine for the D programming language.

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.

gfx:core - Core utilies

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

import gfx.core.rc;

class SomeResource : AtomicRefCounted
{
    mixin(atomicRcCode);

    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 AtomicRefCounted 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. Coordinate system is the same as Vulkan.

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. SPIRV-Cross inserts Y axis inversion, so 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 more...

gfx:decl

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

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();
window.show(640, 480);

Authors:
  • Rémi Thebault
Sub packages:
gfx:bindings, gfx:core, gfx:decl, gfx:genmesh, gfx:gl3, gfx:math, gfx:memalloc, gfx:window, gfx:vulkan, gfx:swapchain, gfx:triangle, gfx:texture, gfx:depth, gfx:stencil, gfx:shadow, gfx:declapi
Dependencies:
spirv_cross, gfx:core
Versions:
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

  • 4 downloads this month

  • 294 downloads total

Score:
0.7
Short URL:
gfx.dub.pm