From Graphics to GPU Compute: A Major Step Forward for the Axmol RHI (blog) #3311
halx99
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Axmol's Render Hardware Interface is evolving from a graphics-oriented abstraction into a broader foundation for modern GPU workloads.
This update introduces first-class cross-backend compute support to the Axmol RHI, together with the resource and shader infrastructure needed to make compute useful in real engine features.
The update includes:
The implementation has been tested successfully across the supported RHI backends.
This is more than adding a single compute API. It gives Axmol a portable way to express both graphics and general-purpose GPU workloads through the same RHI architecture.
Why Compute Support Matters
Traditional rendering pipelines are centered around vertex shaders, fragment shaders, render passes, and draw calls.
Many modern real-time workloads do not naturally fit into that model:
These tasks are often better expressed through compute shaders.
Without a portable compute abstraction, engine-level features tend to fall back to native platform APIs as soon as they need GPU compute. That quickly breaks the purpose of having an RHI in the first place.
The goal of this work is therefore not to add a special path for one effect. Compute is now a first-class RHI capability.
GraphicsPipeline and ComputePipeline
As part of the architectural cleanup, the previous:
has been renamed to:
and a new:
has been introduced.
The distinction is now explicit:
The graphics device can create compute programs and pipelines:
Compute work is submitted through
GraphicsContext::dispatch():rhi::ComputeDispatchDesc desc; desc.pipeline = pipeline; desc.programState = programState; desc.groupCountX = x; desc.groupCountY = y; desc.groupCountZ = z; context->dispatch(desc);The first version submits compute work on the graphics queue, with backend-specific synchronization handled by the RHI implementation.
Storage Buffers: Connecting Compute and Graphics
Useful compute workloads need more than dispatch.
They need GPU-visible data that can be read, written, and consumed by later stages of the frame.
The RHI now supports storage buffers through
BufferDesc:The portable HLSL forms currently supported are:
StructuredBuffer<T> RWStructuredBuffer<T>Shader reflection records the information required by each backend, including:
Storage buffers are not limited to compute shaders. Graphics stages can consume them as well.
That enables workflows such as:
Axmol's new compute dispatch test uses exactly this pattern.
3D Textures
Compute-heavy features such as particle simulation often depend on volumetric data, vector fields, or 3D noise textures.
The RHI now includes:
TextureType::TEXTURE_3Dand:
together with 3D update APIs:
updateData3D(...) updateSubData3D(...)Each backend maps this to its native resource representation. Vulkan, for example, uses 3D images and 3D image views for this texture type.
Compute Shader Reflection
Axmol remains HLSL-first.
Compute shaders are integrated into the existing shader archive and runtime reflection system rather than introducing a second, separate resource model.
A typical compute entry point looks like:
axslccstores the local workgroup size in shader reflection, and the runtime exposes it through the program.Uniform buffers, sampled textures, samplers, and storage buffers continue to use the same
Program/ProgramStatemodel already used by graphics shaders.This is important: graphics and compute are different pipeline types, but they share one resource-binding architecture.
Runtime Sampler Overrides
The update also adds per-
ProgramStatesampler overrides for custom samplers.For example:
This is useful when filter or wrap state needs to change dynamically without mutating a shared texture object.
Built-in sampler presets remain immutable.
OpenGL and OpenGL ES Without Raising Every Shader Profile
OpenGL and OpenGL ES require special care because compute support raises the minimum shader profile:
That does not mean every ordinary graphics shader should be compiled for those profiles.
The shader build system now supports per-shader target overrides.
A compute shader can request:
while ordinary graphics shaders can remain:
At runtime, Axmol selects the highest archived profile that is not newer than the active device profile.
As a result, an OpenGL 4.3 context can load both:
while an OpenGL 3.3 context can continue loading normal graphics shaders but cannot activate the compute workload.
This avoids raising the minimum graphics requirements just because a subset of shaders needs compute.
Compute-Capable GL / GLES Context Selection
The context creation path has also been updated.
On Windows and Linux desktop OpenGL, Axmol prefers:
and falls back to:
when the newer context is unavailable and fallback is allowed.
On Windows GLES, Axmol prefers:
and can fall back to:
Android GLES follows the same general strategy: prefer a GLES 3.1 context, then fall back to GLES 3.0.
The important behavior is:
Cross-Backend Implementation
The compute infrastructure is implemented across:
Each backend maps the RHI abstraction to its native compute and resource model.
Engine-level code does not need to directly deal with platform-specific concepts such as:
Those details stay inside the RHI.
That is one of the most important outcomes of this work: compute no longer needs to be a platform-specific engine feature.
The First Real Consumer: Effekseer GPU Particles
The first large-scale consumer of the new compute path is Effekseer GPU particles.
Previously, the Axmol Effekseer backend did not provide a GPU particle system or GPU particle factory.
The new implementation enables them when the current device provides the required capabilities.
Before creating the GPU particle system, Axmol checks for:
If the requirements are not met, GPU particles are simply unavailable while the existing renderer continues to work.
In other words:
Compute is treated as a capability, not as a new hard requirement for the entire engine.
Effekseer Shader Migration
Effekseer's GPU particle compute shaders are now integrated into Axmol's HLSL-first shader toolchain.
Compute-related shaders are built for compute-capable profiles:
while continuing to use Axmol's existing:
ProgramProgramStateThe Effekseer integration therefore does not bypass the RHI.
Instead, it acts as a real-world validation that the new compute abstraction is general enough for a substantial engine feature.
Validation: Compute Write, Graphics Read
In addition to Effekseer GPU particles, the update adds a dedicated compute dispatch test.
The test performs:
This validates much more than shader compilation.
The path covers:
The supported RHI backends have been tested successfully with the new implementation.
Scope of the First Compute API
The first compute API intentionally focuses on a portable and practical baseline.
It currently supports:
StructuredBufferRWStructuredBufferIt does not currently expose:
These can be added later when real engine workloads require them without changing the overall graphics/compute pipeline architecture introduced here.
What This Enables Next
Effekseer GPU particles are the first use case, not the last one.
With compute now available through the RHI, Axmol can gradually explore workloads such as:
The key difference is that these features can now be designed once at the RHI level instead of independently for Vulkan, Metal, Direct3D, and OpenGL.
From Render Hardware Interface to a Broader GPU Abstraction
The original role of the Axmol RHI was primarily to unify rendering across graphics APIs.
With compute support, that architecture is expanding:
This does not change Axmol's lightweight and portable direction.
The goal is the opposite:
Effekseer GPU particles are the first major feature built on top of the new compute path.
More can now follow.
Axmol
https://axmol.dev/
All reactions