Compute Shaders
Overview
The compute shader API provides two classes for dispatching GPU compute work:
ComputeShaderElement– low-level compute shader element with full control over parameter binding, dispatch modes, and GPU pipeline selection.ComputeShader– lightweight RAII wrapper for the common case of creating a shader by name and dispatching work.
Warning
Avoid using ComputeShaderElement directly. It returns a raw
pointer from new_compute_shader() that must be manually deleted,
making it easy to leak memory. Prefer ComputeShader which
manages lifetime automatically via eastl::unique_ptr.
Usage
Creating a compute shader
Use the ComputeShader RAII wrapper:
#include <shaders/dag_computeShaders.h>
ComputeShader cs("my_compute_shader");
if (cs)
cs.dispatchThreads(width, height, 1);
Setting parameters
Shader parameters are set via variable IDs obtained from
get_shader_variable_id():
int varId = get_shader_variable_id("some_param");
cs->set_color4_param(varId, Color4(1, 0, 0, 1));
cs->set_texture_param(texVarId, textureId);
Dispatching work
There are three dispatch modes:
By thread groups –
ComputeShaderElement::dispatch()dispatches the specified number of thread groups directly.By total threads –
ComputeShaderElement::dispatchThreads()takes the desired total thread count and automatically divides by the shader’s thread group sizes (rounding up).Indirect –
ComputeShaderElement::dispatch_indirect()reads dispatch arguments from a GPU buffer. The buffer must contain 3uint32_tvalues (groupCountX,groupCountY,groupCountZ) at the given byte offset. The buffer must be created withSBCF_BIND_UNORDEREDandSBCF_MISC_DRAWINDIRECTflags (e.g. viad3d::buffers::create_ua_indirectwithIndirect::Dispatch). When storing multiple dispatch entries in a single buffer, the byte offset should be a multiple ofDISPATCH_INDIRECT_BUFFER_SIZE(12 bytes).
// Dispatch by thread groups
cs->dispatch(groupsX, groupsY, groupsZ);
// Dispatch by total thread count (auto-divides by thread group size)
cs->dispatchThreads(totalX, totalY, totalZ);
// Indirect dispatch from a GPU buffer
cs->dispatch_indirect(argsBuffer, byteOffset);
API Reference
Functions
-
ComputeShaderElement *new_compute_shader(const char *shader_name, bool optional = false)
Creates a ComputeShaderElement from a DSHL shader class name.
- Parameters:
shader_name – Name of the compute shader class defined in DSHL.
optional – If true, returns nullptr instead of asserting when the shader is not found.
- Returns:
Pointer to a new ComputeShaderElement, or nullptr if
optionalis true and the shader was not found.
-
class ComputeShaderElement : public DObject
- #include <dag_computeShaders.h>
Compute shader element with full control over parameter binding and dispatch.
Created via new_compute_shader(). Wraps a ScriptedShaderMaterial and provides methods to set shader parameters, query thread group sizes, and dispatch compute work on the GPU.
Subclassed by MeshShaderElement
Parameter setters
Set shader parameters by variable ID (obtained from get_shader_variable_id()).
- return:
true if the variable was found and set successfully.
-
bool set_int_param(const int variable_id, const int v)
-
bool set_color4_param(const int variable_id, const struct Color4&)
Parameter getters
Query current parameter values.
- return:
true if the variable exists.
-
bool hasVariable(const int variable_id) const
-
bool getColor4Variable(const int variable_id, Color4 &value) const
-
bool getIntVariable(const int variable_id, int &value) const
Dispatch
-
eastl::array<uint16_t, 3> getThreadGroupSizes() const
Returns the thread group sizes (X, Y, Z) declared in the shader.
-
bool dispatch(int tgx, int tgy, int tgz, GpuPipeline gpu_pipeline = GpuPipeline::GRAPHICS, bool set_states = true) const
Dispatches the specified number of thread groups.
- Parameters:
tgx – Number of thread groups in X.
tgy – Number of thread groups in Y.
tgz – Number of thread groups in Z.
gpu_pipeline – GPU pipeline to dispatch on.
set_states – If true, binds shader states before dispatch.
- Returns:
true on success.
-
bool dispatchThreads(int threads_x, int threads_y, int threads_z, GpuPipeline gpu_pipeline = GpuPipeline::GRAPHICS, bool set_states = true) const
Dispatches by total thread count, automatically dividing by thread group sizes (rounding up).
- Parameters:
threads_x – Total threads in X.
threads_y – Total threads in Y.
threads_z – Total threads in Z.
gpu_pipeline – GPU pipeline to dispatch on.
set_states – If true, binds shader states before dispatch.
- Returns:
true on success.
-
uint32_t getWaveSize() const
Returns the wave/warp size for this shader.
-
inline bool dispatch(GpuPipeline gpu_pipeline = GpuPipeline::GRAPHICS, bool set_states = true) const
Dispatches a single thread group (1, 1, 1).
-
bool dispatch_indirect(Sbuffer *args, int ofs, GpuPipeline gpu_pipeline = GpuPipeline::GRAPHICS, bool set_states = true) const
Dispatches using indirect arguments read from a GPU buffer.
- Parameters:
args – Buffer containing dispatch arguments (3 uint32_t values: groupCountX, groupCountY, groupCountZ). Must be created with SBCF_BIND_UNORDERED and SBCF_MISC_DRAWINDIRECT flags (e.g. via d3d::buffers::create_ua_indirect with Indirect::Dispatch).
ofs – Byte offset into
argswhere the arguments start. Must be a multiple of DISPATCH_INDIRECT_BUFFER_SIZE (12 bytes) when accessing sequential dispatch entries in the buffer.gpu_pipeline – GPU pipeline to dispatch on.
set_states – If true, binds shader states before dispatch.
- Returns:
true on success.
Public Functions
-
ComputeShaderElement(ScriptedShaderMaterial *ssm, ShaderElement *selem = nullptr)
- Parameters:
ssm – Scripted shader material that defines this compute shader.
selem – Optional shader element override; if null, created from
ssm.
-
~ComputeShaderElement()
-
const char *getShaderClassName() const
Returns the DSHL shader class name.
-
bool setStates() const
Binds shader states without dispatching.
-
class ComputeShader
- #include <dag_computeShaders.h>
Lightweight RAII wrapper around ComputeShaderElement for common dispatch patterns.
Manages the lifetime of the underlying ComputeShaderElement and provides a simplified dispatch interface that always uses GpuPipeline::GRAPHICS.
Public Functions
-
ComputeShader() = default
-
inline ComputeShader(const char *shader_name, bool optional = false)
Constructs a compute shader from a DSHL shader class name.
- Parameters:
shader_name – Name of the compute shader class. If nullptr, creates an empty (invalid) shader.
optional – If true, silently handles missing shaders instead of asserting.
-
inline bool dispatchThreads(int threads_x, int threads_y, int threads_z) const
Dispatches by total thread count, auto-dividing by thread group sizes.
-
inline bool dispatchGroups(int groups_x, int groups_y, int groups_z) const
Dispatches the specified number of thread groups.
-
inline bool dispatchIndirect(Sbuffer *args, int ofs) const
Dispatches using indirect arguments from a GPU buffer.
-
inline explicit operator bool() const
Returns true if the shader was loaded successfully.
Private Members
-
eastl::unique_ptr<ComputeShaderElement> elem
-
ComputeShader() = default