Skip to content
/ groufix Public

Cross-platform and thread-friendly graphics engine primarily focused on Vulkan, built in C.

Notifications You must be signed in to change notification settings

Ckef/groufix

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

groufix

groufix is a cross-platform, thread-friendly and hardware accelerated graphics engine built in C11. The library is primarily focused on the Vulkan API (1.1+). It is compatible with C11 and up, GNU++11 and up and C++20 and up. The main repository is hosted on GitHub.

The engine currently supports the following targets:

Building

Check out all source code:

git clone https://github.com/Ckef/groufix.git
cd groufix
git submodule update --init --recursive

The project is shipped with a Makefile, run make or mingw32-make without a target to view all possible build targets. Each supported operating system has an explicit target. It is also possible to cross-compile groufix to Windows using the mingw-w64 package.

The Makefile takes the following flags:

  • CC=xxx tells the Makefile to use a given compiler collection. xxx defaults to gcc, to cross-compile to Windows, this must be set to i686-w64-mingw32-gcc or x86_64-w64-mingw32-gcc.

  • DEBUG=xxx tells the Makefile whether or not to compile groufix with debug options enabled. If not compiling with debug options, optimization settings will be applied. xxx can be either ON or OFF and defaults to ON.

    • SANITIZE=xxx tells the Makefile to enable sanitizers. This setting is ignored if not compiling with debug options. xxx can be any -fsanitize option, e.g. address,undefined.
  • USE_WAYLAND=xxx tells the Makefile whether to compile for Wayland or not, as it will default to X11 when building on Linux. xxx can be either ON or OFF and defaults to OFF.

Dependencies

Most major dependencies are included as submodules in the repository (see the deps/ directory). They are automatically built and linked by the included Makefile.

To build and run with debug options enabled, the VulkanSDK needs to be installed on your system. All other dependencies based on your setup are:

When building on Linux:

  • gcc or clang : for building source files, use the CC flag to pick a compiler collection.
  • make and cmake : for building source files.
  • xorg-dev or libwayland-dev : for building GLFW.
  • python3 : for building Shaderc.

When cross-compiling to Windows:

  • mingw-w64 : for building source files for windows (in addition to the above packages), the CC flag needs to be set as described under #Building.

When building on Windows:

  • CMake and Mingw-w64 need to be installed, which should include the cmake.exe and mingw32-make.exe binaries. To use these to build groufix, add the bin directory of both to your PATH variable. Make sure to install the compiler using POSIX threads.
  • Git and Python 3 need to be installed for building Shaderc, make sure to install both to your PATH variable.

Usage

Once groufix is built and used by an executable, the following environment variables can be set:

  • GROUFIX_DEFAULT_LOG_LEVEL : used to set the default log level during init. Value can be set to one of NONE,FATAL,ERROR,WARN,INFO,DEBUG,VERBOSE,ALL, case insensitive.

  • GROUFIX_PRIMARY_VK_DEVICE : used to influence the primary device selection. It will prioritize matching physical Vulkan devices. A device matches if the set value is a substring of its name, case insensitive.

All core functionality can be included in your code with #include <groufix.h>. To use the engine, it must be initialized with a call to gfx_init. The thread that initializes the engine is considered the main thread. Any other function of groufix cannot be called before gfx_init has returned succesfully, the only exceptions being gfx_terminate, gfx_attach, gfx_detach and the gfx_log* function family. When the engine will not be used anymore, it must be terminated by the main thread with a call to gfx_terminate. Once the engine is terminated, it behaves exactly the same as before initialization.

  • groufix will not clean up after you. This means that any object you create or initialize should be destroyed or cleared by you as well, before termination. In practice this means any call to a gfx_create_* or gfx_*_init function should be followed up by a call to the associated gfx_destroy_* and gfx_*_clear functions.

All names starting with gfx or GFX are reserved by groufix, using any such name in conjunction with the engine might result in redefinitions.

Threading

Similarly to initializing the engine, any thread that wants to make any groufix calls needs to attach itself to the engine with a call to gfx_attach. Before an attached thread exits, it must be detached with a call to gfx_detach. The main thread is the only exception, it does not have to be explicitly attached or detached. The threading model is designed around low overhead in multiple concurrent threads, it aims to stall as little as possible when accessing objects. The following rules are defined for all groufix objects to aid in this goal:

  • groufix will not reference count. This means that whenever you destroy, clear or free an object with a call to the associated gfx_destroy_*, gfx_*_clear or gfx_free_* function, any other object may not reference this object anymore. If an object is still referenced during any such call, behaviour is undefined.

  • groufix objects are not thread-safe. Function calls that operate on the same object (or descendants thereof) are not synchronized and cannot be called concurrently from different threads. However, objects referencing each other that do not share a common ancestor created with a call to gfx_create_* are internally synchronized and can always be operated on concurrently. For example, simultaneously operating on a GFXRenderer and a GFXHeap (or GFXWindow) referenced by it is thread-safe.

  • All functions directly related to the window manager of the host platform are thread-affine. These functions can only be called from the main thread. These functions are gfx_poll_events, gfx_wait_events and all functions defined in groufix/core/window.h (these are the gfx_*monitor* and gfx_*window* function families). All other functions can be called from any thread.

When an exception is made to any of the listed rules, this will always be noted alongside the relevant functions of the object in question. The following are a few of the most noteworthy exceptions:

  • Devices : Any function that takes a GFXDevice is thread-safe with respect to that given device.

  • Heap allocations : To facilitate concurrent creation of resources, all gfx_alloc_* and gfx_free_* functions are thread-safe with respect to the GFXHeap.

  • Resource operations : To facilitate concurrent modification of memory resources, operations performed on different resources are thread-safe with respect to the GFXHeap that allocated them.

  • Dependency objects : To facilitate concurrent synchronization of resources, the gfx_dep_* macro family is thread-safe with respect to the GFXDependency.

  • Techniques and sets : To facilitate concurrent creation and modification of resources, the gfx_*tech* and gfx_*set* function families are thread-safe with respect to the GFXRenderer.

    • Except for modification during frame operations, i.e. during gfx_renderer_acquire or from the moment gfx_frame_start is called up until gfx_frame_submit returns.
  • Recorders : To facilitate concurrent initialization of threads and subsequent threaded recording, the gfx_*recorder* function family is thread-safe with respect to the GFXRenderer.

    • Except for creation and modification during frame operations, much like modification of techniques and sets.

About

Cross-platform and thread-friendly graphics engine primarily focused on Vulkan, built in C.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages