Pipeline state configuration

DSHL has some state variables that are used for configuring fixed pipeline stages (blending, depth/stencil testing, etc.). You can optionally define them inside a shader.

Blending

Blending settings can be configured in DSHL shader using the following syntax:

blend_target = blend_factor;

where blend_target is one of these state variables

  • blend_src – blend source

  • blend_dst – blend destination

  • blend_asrc – blend alpha source

  • blend_adst – blend alpha destination

and blend_factor is one of these keywords:

Keyword

Description

RGB Blend Factor

Alpha Blend Factor

zero or 0

Zero

(0, 0, 0)

0

one or 1

One

(1, 1, 1)

1

sc

Source Color

(R_s, G_s, B_s)

A_s

isc

Inverse Source Color

(1 - R_s, 1 - G_s, 1 - B_s)

1 - A_s

sa

Source Alpha

(A_s, A_s, A_s)

A_s

isa

Inverse Source Alpha

(1 - A_s, 1 - A_s, 1 - A_s)

1 - A_s

dc

Destination Color

(R_d, G_d, B_d)

A_d

idc

Inverse Destination Color

(1 - R_d, 1 - G_d, 1 - B_d)

1 - A_d

da

Destination Alpha

(A_d, A_d, A_d)

A_d

ida

Inverse Destination Alpha

(1 - A_d, 1 - A_d, 1 - A_d)

1 - A_d

sasat

Source Alpha Saturation

(f, f, f); f = min(A_s, 1 - A_d)

1

bf

Blend Constant

(R_c, G_c, B_c)

A_c

ibf

Inverse Blend Constant

(1 - R_c, 1 - G_c, 1 - B_c)

1 - A_c

where

  • (R_s, G_s, B_s) and A_s represent R, G, B, A components of the source (new value which shader just produced)

  • (R_d, G_d, B_d) and A_d represent R, G, B, A components of the destination (old value in the current render target)

  • (R_c, G_c, B_c) and A_c represent configurable blend constants

Blending is performed using the following pseudocode:

if (blendEnable) {
  finalColor.rgb = (srcColorBlendFactor * srcColor.rgb) <colorBlendOp> (dstColorBlendFactor * dstColor.rgb);
  finalColor.a = (srcAlphaBlendFactor * srcColor.a) <alphaBlendOp> (dstAlphaBlendFactor * dstCoilor.a);
} else {
    finalColor = srcColor;
}

finalColor = finalColor & colorWriteMask;

Example:

blend_src = sa; blend_dst = 1;
blend_asrc = sa; blend_adst = 1;

Warning

Blending operations (as well as blending constants for bf and ibf blending modes) need to be configured in C++ code.

If you don’t configure blending factors in the shader, these defaults will be used:

blend_src = 1; blend_dst = 0;
blend_asrc = 1; blend_adst = 0;

Independent blending

Dagor supports independent blending, i.e. different render targets may have different blending settings. This is done by providing an index to blend_src, blend_dst, blend_asrc, blend_adst variables with [] operator.

blend_src[0] = 1; blend_dst[0] = 0;
blend_src[1] = 0; blend_dst[1] = 1;

Without an index, the desired blend factor affects all render targets.

Depth/Stencil

Depth and stencil tests can also be configured in DSHL using similar syntax.

Depth state variables

z_write – enables/disables writing to depth buffer. Valid values: true / false. Default value: true.

z_test – enables/disables depth testing. Valid values: true / false. Default value: true.

z_func – specifies comparison function for depth testing. Valid values:

  • equal evaluates to \(\text{reference} = \text{test}\)

  • notequal evaluates to \(\text{reference} \neq \text{test}\)

  • always always evaluates to true

Default value is GREATER_OR_EQUAL (evaluates to \(\text{reference} \geq \text{test}\)). Note that this value cannot be set explicitly, as it is the default behavior, because Dagor follows the convention that closer objects have more depth value.

Example:

z_write = false;
z_test = true;
z_func = always;

Stencil state variables

stencil – enables/disables stencil test. Valid values: true / false. Default value: false.

stencil_func – specifies comparison function for stencil testing. Valid values:

  • never always evaluates to false

  • less evaluates to \(\text{reference} < \text{test}\)

  • equal evaluates to \(\text{reference} = \text{test}\)

  • lessequal evaluates to \(\text{reference} \leq \text{test}\)

  • greater evaluates to \(\text{reference} > \text{test}\)

  • notequal evaluates to \(\text{reference} \neq \text{test}\)

  • greaterequal evaluates to \(\text{reference} \geq \text{test}\)

  • always always evaluates to true

stencil_ref – specifies reference value for the stencil test. Valid values: int, clamped to [0, 255] range.

stencil_pass – specifies the action performed on samples that pass both stencil and depth tests.

stencil_fail – specifies the action performed on samples that fail the stencil test.

stencil_zfail – specifies the action performed on samples that pass the stencil test and fail the depth test.

Valid actions:

  • keep – keeps the current value.

  • zero – sets the value to 0.

  • replace – sets the value to reference stencil_ref value

  • incrsat – increments the current value and clamps to [0, 255]

  • decrsat – decrements the current value and clamps to [0, 255]

  • incr – increments the current value and wraps to 0 when the maximum value would have been exceeded.

  • decr – decrements the current value and wraps to 255 the maximum possible value when the value would go below 0.

Example:

stencil = true;
stencil_func = always;
stencil_pass = replace;
stencil_ref = 255;
stencil_zfail = keep;
stencil_fail = keep;

Culling

cull_mode specifies culling mode.

  • ccw – counterclockwise.

  • cw – clockwise.

  • none – no culling is done.

Default value is ccw.

Example:

cull_mode = cw;

Alpha to coverage

Alpha to coverage (A2C) maps the alpha output value from a pixel shader to the coverage mask of MSAA. This feature might be helpful for smoothing out the edges of alpha-tested texture (e.g. vegetation).

For example, with 4x MSAA and A2C enabled, if the output alpha of a pixel is 0.5, only 2 of the 4 coverage samples will store the color.

Can be toggled by setting alpha_to_coverage to true / false.

View instancing

View instancing feature allows a shader to be run multiple times in a single draw call to draw different view instances. The SV_ViewID semantic is provided to the shader which defines the index of the view instance. This feature is supported only on DX12 and enforces Shader Model 6.1 compilation.

Maximum number of view instances is defined by MAX_VIEW_INSTANCES = 4. For example, using view instancing, you can capture a cube shadow map for a point light in 2 render passes with 3 view instances per pass.

Valid syntax is view_instances = 1..4.

view_instances = 1 means one instance (which is the default case).

Color write mask

Color write mask can be configured with color_write state variable. You can set the mask via RGBA swizzle or by an int number (in [0, 15] range). So r = 0b0001, g = 0b0010, b = 0b0100, a = 0b1000.

For example,

color_write = rg;
// color_write = 3 is the same
// 3 = 0b0011 = rg

Color mask supports multiple render targets, i.e. for each render target the mask can be different. You can use [] operator to specify the mask for the specific render target.

color_write = true; // sets RGBA for all RT
color_write[1] = rg; // sets RG for RT[1]

By default, color mask is RGBA for all render targets.