Enhancing DirectX Testing with AMD Smoldr

Originally posted:
Sebastian Neubauer's avatar
Sebastian Neubauer

Writing small graphics applications and running them has historically not been a small feat. Especially with the emergence of low-level APIs like Microsoft DirectX® 12 and Vulkan™, it takes many lines of code for setup until shader code is running on a GPU.

With Google’s release of Amber, this changed for Vulkan. Amber made it possible to declare buffers and shaders and run them on the GPU, all in just a few lines of code. Until now, we were missing an equivalent for DirectX.

Today, we are releasing AMD Smoldr, a simple scripting tool to run DirectX 12 shaders on GPUs using a text input file.

What is Smoldr?

Smoldr allows compiling HLSL shaders through DXIL, creating pipelines, resources, views, and then binding and running a compute dispatch. This is all controlled by a text based script file – no C++ development needed.

The project is open-source (GitHub repository), contributions are welcome. Note that Smoldr is work-in-progress, the script syntax is not fixed and may change in the future. Being a command-line tool, the focus so far is compute, so compute shaders work well, but all of raytracing is supported too!

One picture script says more than a thousand words, so here is an example on how it looks, adding together the content of two buffers and writing the results into a third:

# Create a HLSL source called csshader
SOURCE csshader
ByteAddressBuffer inbuf[2] : register(t0); // SRV
RWByteAddressBuffer outbuf : register(u0); // UAV
// One workgroup consists of 32 threads
[numthreads(32, 1, 1)]
void CSMain(uint3 DTid : SV_DispatchThreadID)
{
// Take 2 numbers from first buffer, one from second, and sum them
unsigned int first_idx = DTid.x * 2;
float first = inbuf[0].Load<float>(first_idx * 4) + inbuf[0].Load<float>((first_idx + 1) * 4);
float sum = first + inbuf[1].Load<float>(DTid.x * 4);
outbuf.Store<float>(DTid.x * 4, sum);
}
END
# Compile the source with dxc into a binary called csobj
OBJECT csobj csshader cs_6_4 CSMain
# Allocate buffers in GPU memory for input and output
BUFFER inbuf DATA_TYPE float SIZE 64 SERIES_FROM 0 INC_BY .25
BUFFER inbuf2 DATA_TYPE float SIZE 32 SERIES_FROM 10.0 INC_BY .25
BUFFER outbuf DATA_TYPE float SIZE 32 FILL 0
# The root signature
ROOT default
TABLE UAV REGISTER 0 NUMBER 1 SPACE 0
TABLE SRV REGISTER 0 NUMBER 2 SPACE 0
END
# Create a compute pipeline called cspipe
PIPELINE cspipe COMPUTE
ATTACH csobj
ROOT default
END
# Create views that point to the complete buffers
VIEW inview inbuf AS SRV
VIEW inview2 inbuf2 AS SRV
VIEW outview outbuf AS UAV
# Run the pipeline with 1x1x1 workgroups, so 32 threads
DISPATCH cspipe
BIND 0 TABLE outview
BIND 1 TABLE inview
RUN 1 1 1
# Outbuf should contain the added inbuf + inbuf2 now
# Check that the shader worked as expected
EXPECT outbuf float OFFSET 0 EQ 10.25 11.5 12.75 14
EXPECT outbuf float OFFSET 64 EQ 30.25 31.5 32.75 34
# Print a buffer's content to the terminal
DUMP outbuf float

Nothing more than that is needed to run a full-fledged DirectX 12 application:

Successful Smoldr run

Smoldr is built to play around with the DirectX 12 API, with drivers and with hardware. That makes it essential to be as helpful as possible when something unexpected happens. Even for just a typo, Smoldr points out where and what went wrong:

Smoldr showing an error message

Other notable features include support for the Microsoft Agility SDK to try out new, experimental HLSL features. Graphics tools like the AMD Radeon™ GPU Profiler can capture Smoldr scripts by using the --window option, spawning a window and executing the script once every frame.

What’s next?

Compute and raytracing pipelines are working well, so the next big thing to support is mesh shaders. Mesh (and amplification) shaders will allow to easily use modern graphics rendering with Smoldr. Look out for that!

Resources

Endnotes

DirectX is either a registered trademark or trademark of Microsoft Corporation in the US and/or other countries.

Vulkan and the Vulkan logo are registered trademarks of the Khronos Group Inc. Other names are for informational purposes only and may be trademarks of their respective owners.

Sebastian Neubauer's avatar

Sebastian Neubauer

Sebastian Neubauer is working in the graphics compiler team at AMD. His focus is LLVM and ray tracing.

Related news and technical articles

Related videos