Vulkan 1.3 implementation for AmigaOS 4.
VulkanOS4 brings the Vulkan graphics API to PowerPC Amiga hardware. It provides a complete Vulkan 1.3 runtime with two installable client drivers (ICDs), a loader library, and a full SDK for developing Vulkan applications on AmigaOS 4.
- vulkan.library -- Vulkan loader. Discovers and dispatches to installed ICDs automatically, selecting the best available driver.
- software_vk.library -- Software ICD. Pure CPU rendering with a SPIR-V bytecode interpreter. Works on any AmigaOS 4 system without GPU requirements. Useful for development, validation, and systems without supported GPUs.
- ogles2_vk.library -- GPU ICD. Hardware-accelerated rendering via ogles2.library and Warp3D Nova. Uses SPIRV-Cross to transpile SPIR-V shaders to GLSL ES 3.1 for GPU execution. Typically 10--300x faster than the software renderer.
- SDK -- Vulkan headers, inline macros, and link library for compiling Vulkan programs on AmigaOS 4.
Both ICDs implement 218 Vulkan functions (100% Vulkan 1.3 core + WSI) and support 210+ SPIR-V opcodes.
- AmigaOS 4.1 Final Edition or later
- PowerPC-based Amiga (AmigaOne X5000, X1000, A1222, Sam460, or similar)
- For software rendering: no additional requirements
- For GPU rendering (ogles2_vk.library):
- Supported Radeon GPU (RX 500/400 series or HD 7000+ series)
- RadeonRX or RadeonHD graphics driver
- Warp3D Nova (Warp3DNova.library)
- ogles2.library (OpenGL ES 2.0)
- Docker
walkero/amigagccondocker:os4-gcc11Docker image (GCC 11.5.0 cross-compiler)- GNU Make
- For the GPU ICD, the following must be downloaded into
external/:- SPIRV-Cross -- SPIR-V to
GLSL transpiler (compiled as
libspirv-cross.a) - VMA -- Vulkan Memory Allocator (C++ header-only, requires g++)
- OGLES2 SDK headers (
external/OGLES2/) - Warp3D Nova SDK headers (
external/Warp3DNova/)
- SPIRV-Cross -- SPIR-V to
GLSL transpiler (compiled as
See external/*/README.md for download and setup instructions for each
dependency.
The distribution includes an Autoinstall script. From the VulkanOS4 directory on your Amiga:
Execute Autoinstall
This installs:
LIBS:vulkan.library-- Vulkan loaderLIBS:Vulkan/software_vk.library-- Software ICDLIBS:Vulkan/ogles2_vk.library-- GPU ICDDEVS:Vulkan/icd.d/software_vk.json-- Software ICD manifestDEVS:Vulkan/icd.d/ogles2_vk.json-- GPU ICD manifestC:vulkaninfo-- Device information toolC:VulkanPrefs-- ICD preferences tool
Copy the files to the following locations:
copy Libs/vulkan.library LIBS:
copy Libs/Vulkan/software_vk.library LIBS:Vulkan/
copy Libs/Vulkan/ogles2_vk.library LIBS:Vulkan/
copy Devs/Vulkan/icd.d/software_vk.json DEVS:Vulkan/icd.d/
copy Devs/Vulkan/icd.d/ogles2_vk.json DEVS:Vulkan/icd.d/
copy Tools/VulkanPrefs C:
copy Tools/vulkaninfo C:
SDK files must be copied manually to your AmigaOS SDK:
copy SDK/include/include_h/vulkan SDK:include/include_h/vulkan ALL CLONE
copy SDK/include/include_h/interfaces/vulkan.h SDK:include/include_h/interfaces/
copy SDK/include/include_h/inline4/vulkan.h SDK:include/include_h/inline4/
copy SDK/include/include_h/proto/vulkan.h SDK:include/include_h/proto/
copy SDK/include/include_h/clib/vulkan_protos.h SDK:include/include_h/clib/
copy SDK/newlib/lib/libvulkan_loader.a SDK:newlib/lib/
Minimal compile command:
gcc -mcrt=newlib -D__USE_INLINE__ -o myapp myapp.c -lvulkan_loader -lauto
Required flags:
-D__USE_INLINE__-- enables inline macros (vkCreateInstance()etc.)-lvulkan_loader-- links the auto-open stub for vulkan.library-lauto-- auto-opens exec.library, intuition.library, etc.
Required includes in your source code:
#include <proto/exec.h> /* always needed */
#include <proto/intuition.h> /* if using windows/WSI */
#include <proto/vulkan.h> /* Vulkan API */A project template is provided in Template/ with a ready-to-use Makefile
and source file.
All components are cross-compiled via Docker. Pull the Docker image first:
docker pull walkero/amigagccondocker:os4-gcc11make test-build # Verify Docker cross-compilation works
make all # Build everything (loader + both ICDs + examples + tools)
make loader # Build vulkan.library + libvulkan_loader.a
make icd # Build software_vk.library
make gpu-icd # Build ogles2_vk.library
make examples # Build all 22 example programs
make tools # Build vulkaninfo, VulkanPrefs, AmigaMark
make dist # Create distribution directory in dist/VulkanOS4/
make dist-lha # Create dist/VulkanOS4.lha archive
make check # Validate build output (ELF header verification)
make clean # Remove all build artifactsmake all builds components in the correct order. To build individually,
the dependencies are:
make loader-- no dependenciesmake icd-- no dependenciesmake gpu-icd-- requires external dependencies (see Requirements)make examples-- depends on loader (for libvulkan_loader.a)make tools-- depends on loader
22 example programs are included, covering basic rendering through to 3D geometry, texturing, instancing, and glTF model loading. Run them from the distribution directory on your Amiga:
Examples/01_enumerate/01_enumerate
Examples/08_triangle/08_triangle
Examples/09_rotating/09_rotating
Examples/12_wireframe_cube/12_wireframe_cube
Examples/20_torus/20_torus
All graphical examples accept an optional -d N (or --duration N)
flag that exits after N seconds. Without the flag, the example runs
until the close gadget is pressed (the original behaviour). Useful
for automated test runs and quick previews:
Examples/08_triangle/08_triangle -d 10 ; auto-exit after 10s
Examples also respond to CTRL-C from the shell they were launched in.
| # | Example | Description |
|---|---|---|
| 01 | 01_enumerate |
Device and extension enumeration |
| 02 | 02_clear |
Screen clear with solid colour |
| 03 | 03_gradient |
Gradient via fragment shader |
| 04 | 04_checkerboard |
Procedural checkerboard pattern |
| 05 | 05_plasma |
Animated plasma effect |
| 06 | 06_rings |
Concentric ring pattern |
| 07 | 07_waves |
Animated wave distortion |
| 08 | 08_triangle |
Classic RGB triangle |
| 09 | 09_rotating |
Rotating triangle with push constants |
| 10 | 10_depth |
Depth buffer testing |
| 11 | 11_textured |
Textured quad with sampler |
| 12 | 12_wireframe_cube |
3D wireframe cube with perspective |
| 13 | 13_solid_cube |
Solid cube with face colouring and lighting |
| 14 | 14_instanced_cubes |
Instanced rendering (3x3 grid) |
| 15 | 15_render_pass |
Legacy render pass API usage |
| 16 | 16_transfer_ops |
Buffer and image transfer commands |
| 17 | 17_events_sync |
Fences, semaphores, and events |
| 18 | 18_query_demo |
Occlusion and timestamp queries |
| 19 | 19_indirect_draw |
Indirect draw commands |
| 20 | 20_torus |
Textured torus with starfield background |
| 21 | 21_image_texture |
Image file loading via stb_image |
| 22 | 22_gltf_viewer |
glTF 2.0 model viewer via cgltf |
| 24 | 24_proc_addr |
vkGetDeviceProcAddr ABI regression test — verifies raw PFN_vk* resolution works across queue/memory/command/sync/WSI categories |
Examples 21 and 22 require optional third-party headers (stb_image.h and cgltf.h respectively). They include procedural fallbacks and will still compile and run without the external headers.
Displays Vulkan device information, supported features, memory properties, and queue families.
vulkaninfo
Manages ICD priority and enable/disable state. Reads and writes
ENVARC:Vulkan/vulkan.prefs.
VulkanPrefs ; Show current ICD configuration
VulkanPrefs -list ; List discovered ICDs
VulkanPrefs -disable sw ; Disable software ICD
VulkanPrefs -enable sw ; Re-enable software ICD
VulkanPrefs -priority gpu 1 ; Set GPU ICD as highest priority
Vulkan benchmark tool. Measures rendering performance with timed FPS reporting.
AmigaMark
VulkanOS4 uses the following third-party libraries and resources:
| Library | Version | Author | License | Usage |
|---|---|---|---|---|
| cglm | 0.9.6 | recp | MIT | API design inspiration for vk_math.h |
| stb_image | 2.30 | Sean Barrett | Public domain / MIT | Optional image loading in examples |
| cgltf | 1.15 | Johannes Kuhlmann | MIT | Optional glTF 2.0 model loading |
| VMA | 3.2.0 | AMD GPUOpen | MIT | GPU/host memory suballocation |
| SPIRV-Cross | latest | Khronos Group | Apache 2.0 | SPIR-V to GLSL ES 3.1 transpiler |
OGLES2 and Warp3D Nova SDK headers are proprietary (A-EON Technology) and must be obtained separately.
See THIRD_PARTY.md for full attribution details.
ABI and compatibility fixes; presentation correctness; build hygiene. Many of the underlying issues were diagnosed by Andrea Palmate' (afxgroup) in PR #1.
ICD changes:
- Fix
vkGetDeviceProcAddrABI: the GPU ICD'sLookupRawProcAddrpreviously fell back to APICALL trampolines for unlisted names, which slid every argument by one register slot when called as rawPFN_vk*. Expanded theRAWtable to mirror the fullDISPATCHtable (~210 entries) and replaced the fallback withreturn NULL. Also extended the SW ICD'sRAWtable with the four surface queries and five swapchain entry points it was missing. - Honour
VK_PRESENT_MODE_FIFO_KHRin the GPU ICD via OGLES2 vsync. The OGLES2 context was previously created withOGLES2_CCT_VSYNC=0hard-coded, regardless of the swapchain'spresentMode. With vsync off,aglSwapBuffersreturned immediately, the CPU loop submitted thousands of frames per second, and the Warp3D Nova compositor's per-refresh sampling produced visible animation skipping on rotating-cube examples regardless of the display's actual refresh rate. NowvkCreateSwapchainKHRtoggles vsync viaaglSetParams2based on the swapchain'spresentMode, so FIFO/FIFO_RELAXED/MAILBOX vsync pace to whatever refresh rate the W3D Nova driver reports. - Give
vkWaitForFencesreal CPU/GPU sync viaglFinish. The GPU ICD's fence wait was a no-op (just flipping a boolean) which let the CPU loop outrun the GPU and queue up frames the compositor never displays. CallingglFinishbefore marking fences signalled matches the standard Vulkan spec semantic and tightens up the frame-time distribution even in FIFO mode (max frame-time dropped from a 1.2 s outlier tail to ~14.7 ms). - Detect SPIR-V endianness from the magic word in the SW ICD, rather
than unconditionally byte-swapping. Per the Vulkan spec, the magic
word may be supplied in either endianness. The previous behaviour
was wrong for callers that already produce host-byte-order SPIR-V
(e.g.
uint32_tarray literals compiled on a big-endian host such as ImGui's__glsl_shader_*_spvarrays on PowerPC). - GPU ICD: force
FORCE_FLATTENED_IO_BLOCKSin SPIRV-Cross and rename vertex/fragment interface-block instances to a commonvaryso Warp3D Nova's name-based GLSL ES linker can match varyings across stages. - GPU ICD: add
VK_FORMAT_R8G8B8A8_UNORM(VkFormat 37) to the vertex attribute mapping withGL_TRUEfor the normalised flag. ImGui packs vertex colour in this format. - GPU ICD: set non-zero defaults for
bufferImageGranularity,nonCoherentAtomSize, the variousmin*OffsetAlignmentandmax*Rangelimits. VMA divides by some of these during init and on every allocation; zeroes causedvmaCreateImageto bail out withVK_ERROR_OUT_OF_DEVICE_MEMORYbefore callingvkAllocateMemory. - Add a
D(...)debug-print macro to both ICDs (no-op whenDEBUGis undefined) and convert the existingIExec->DebugPrintFcall sites. Lets release builds skip the trace overhead.
Examples and tests:
- New regression test example
24_proc_addr: 23 assertions across 7 function categories verifying thatvkGetDeviceProcAddrreturns raw C-ABI pointers (no APICALL trampolines), so any future drift between theDISPATCHandRAWtables fails on first run. - All graphical examples accept
-d N/--duration Nto exit after N seconds. Default behaviour (no flag) unchanged. Animated examples checktime(NULL)in the render loop; render-once examples use a multi-signalWaiton the window port +timer.device+ CTRL-C. 21_image_texture/22_gltf_viewernow skip the-d Nflag when scanning argv for their positional file argument, so they can be used in automated test sweeps without spurious "file not found" fallbacks.
Build / loader:
- Wire
$(DEBUG)into the Docker build recipes for the loader and both ICDs (previously the variable existed but never reached the compiler). - Refactor
software_icd/Makefile.crossto use pattern rules instead of a single 80-line&&-chained shell pipeline; supports incremental builds andmake -j. - Replace
strncpy+ manual null-terminate withsnprintfin the loader ICD path tracking to silence a-Wstringop-truncationwarning.
Initial release.
- Vulkan 1.3 loader (
vulkan.library) with automatic ICD discovery and dispatch - Software ICD (
software_vk.library) with SPIR-V bytecode interpreter, triangle rasteriser with depth testing, and Bresenham line rasteriser - GPU ICD (
ogles2_vk.library) with OGLES2/Warp3D Nova backend and SPIRV-Cross transpiler for SPIR-V to GLSL ES 3.1 - 218 Vulkan functions per ICD (100% Vulkan 1.3 core + WSI coverage)
- 210+ SPIR-V opcodes including vertex/fragment shader operations, matrix math, texture sampling, control flow, and type conversions
- 22 example programs from basic triangle to glTF model viewer
- SDK headers with AmigaOS interface definitions, inline macros, and link library
- VulkanPrefs CLI tool for ICD priority management
- vulkaninfo device enumeration tool
- AmigaMark benchmark tool
- Autoinstall script for AmigaOS 4
- Optimised software rasteriser with incremental edge functions, active varying mask, and shader state allocation pooling
- GPU ICD optimisations including VBO caching and batched resource cleanup
See individual source files for license information.