1307 lines
39 KiB
Markdown
1307 lines
39 KiB
Markdown
# AmberScript
|
||
* DRAFT
|
||
|
||
This document defines the script input language for the Amber system. The format
|
||
is based on the Talvos format, VkRunner format, and VkScript proposed format.
|
||
|
||
## Specification
|
||
All amber scripts must start with `#!amber` as the first line. Comments are
|
||
specified by a # character and continue to the end of the line, except in
|
||
inlined shader source code, where AmberScript comments are not
|
||
possible. Keywords are case sensitive. All names are made up of ASCII
|
||
characters, and delimited by whitespace.
|
||
|
||
TODO(dneto): What characters are valid in a name?
|
||
|
||
### Number literals
|
||
|
||
Literal numbers are normally presented in decimal form. They are interpreted
|
||
as integers or floating point depending on context: a command parameter is
|
||
predefined as either integral or floating point, or the data type is
|
||
user-specified (such as for buffer data).
|
||
|
||
Hex values: Whenever an integer is expected, you may use a hexadecimal number,
|
||
which is the characters `0x` followed by hexadecimal digits.
|
||
|
||
### Requesting features
|
||
|
||
If specific device features are required you can use the `DEVICE_FEATURE`
|
||
command to enable them.
|
||
|
||
```groovy
|
||
DEVICE_FEATURE vertexPipelineStoresAndAtomics
|
||
DEVICE_FEATURE VariablePointerFeatures.variablePointersStorageBuffer
|
||
```
|
||
|
||
Currently each of the items in `VkPhysicalDeviceFeatures` are recognized along
|
||
with:
|
||
* `VariablePointerFeatures.variablePointers`
|
||
* `VariablePointerFeatures.variablePointersStorageBuffer`
|
||
* `Float16Int8Features.shaderFloat16`
|
||
* `Float16Int8Features.shaderInt8`
|
||
* `Storage8BitFeatures.storageBuffer8BitAccess`
|
||
* `Storage8BitFeatures.uniformAndStorageBuffer8BitAccess`
|
||
* `Storage8BitFeatures.storagePushConstant8`
|
||
* `Storage16BitFeatures.storageBuffer16BitAccess`
|
||
* `Storage16BitFeatures.uniformAndStorageBuffer16BitAccess`
|
||
* `Storage16BitFeatures.storagePushConstant16`
|
||
* `Storage16BitFeatures.storageInputOutput16`
|
||
* `SubgroupSizeControl.subgroupSizeControl`
|
||
* `SubgroupSizeControl.computeFullSubgroups`
|
||
* `SubgroupSupportedOperations.basic`
|
||
* `SubgroupSupportedOperations.vote`
|
||
* `SubgroupSupportedOperations.arithmetic`
|
||
* `SubgroupSupportedOperations.ballot`
|
||
* `SubgroupSupportedOperations.shuffle`
|
||
* `SubgroupSupportedOperations.shuffleRelative`
|
||
* `SubgroupSupportedOperations.clustered`
|
||
* `SubgroupSupportedOperations.quad`
|
||
* `SubgroupSupportedStages.vertex`
|
||
* `SubgroupSupportedStages.tessellationControl`
|
||
* `SubgroupSupportedStages.tessellationEvaluation`
|
||
* `SubgroupSupportedStages.geometry`
|
||
* `SubgroupSupportedStages.fragment`
|
||
* `SubgroupSupportedStages.compute`
|
||
|
||
|
||
Extensions can be enabled with the `DEVICE_EXTENSION` and `INSTANCE_EXTENSION`
|
||
commands.
|
||
|
||
```groovy
|
||
DEVICE_EXTENSION VK_KHR_get_physical_device_properties2
|
||
INSTANCE_EXTENSION VK_KHR_storage_buffer_storage_class
|
||
```
|
||
|
||
### Setting Engine Configuration
|
||
|
||
In some instances there is extra data we want to provide to an engine for
|
||
configuration purposes. The `SET ENGINE_DATA` command allows that for the given
|
||
set of data types.
|
||
|
||
#### Engine Data Variables
|
||
* `fence_timeout_ms` - value must be a single uint32 in milliseconds.
|
||
|
||
```groovy
|
||
SET ENGINE_DATA {engine data variable} {value}*
|
||
```
|
||
|
||
### Virtual File Store
|
||
|
||
Each amber script contains a virtual file system that can store files of textual
|
||
data. This lets you bundle multiple source files into a single, hermetic amber
|
||
script file.
|
||
|
||
Virtual files are declared using the `VIRTUAL_FILE` command:
|
||
|
||
```groovy
|
||
VIRTUAL_FILE {path}
|
||
{file-content}
|
||
END
|
||
```
|
||
|
||
Paths must be unique.
|
||
|
||
Shaders can directly reference these virtual files for their source. \
|
||
HLSL shaders that `#include` other `.hlsl` files will first check the virtual
|
||
file system, before falling back to the standard file system.
|
||
|
||
### Shaders
|
||
|
||
Shader programs are declared using the `SHADER` command. \
|
||
Shaders can be declared as `PASSTHROUGH`, with inlined source or using source
|
||
from a `VIRTUAL_FILE`.
|
||
|
||
Pass-through shader:
|
||
|
||
```groovy
|
||
# Creates a passthrough vertex shader. The shader passes the vec4 at input
|
||
# location 0 through to the `gl_Position`.
|
||
SHADER vertex {shader_name} PASSTHROUGH
|
||
```
|
||
|
||
Shader using inlined source:
|
||
|
||
```groovy
|
||
# Creates a shader of |shader_type| with the given |shader_name|. The shader
|
||
# will be of |shader_format|. The shader source then follows and is terminated
|
||
# with the |END| tag.
|
||
SHADER {shader_type} {shader_name} {shader_format} [ TARGET_ENV {target_env} ]
|
||
{shader_source}
|
||
END
|
||
```
|
||
|
||
Shader using source from `VIRTUAL_FILE`:
|
||
|
||
```groovy
|
||
# Creates a shader of |shader_type| with the given |shader_name|. The shader
|
||
# will be of |shader_format|. The shader will use the virtual file with |path|.
|
||
SHADER {shader_type} {shader_name} {shader_format} [ TARGET_ENV {target_env} ] VIRTUAL_FILE {path}
|
||
```
|
||
|
||
`{shader_name}` is used to identify the shader to attach to `PIPELINE`s,
|
||
|
||
`{shader_type}` and `{shader_format}` are described below:
|
||
|
||
#### Shader Type
|
||
* `vertex`
|
||
* `fragment`
|
||
* `geometry`
|
||
* `tessellation_evaluation`
|
||
* `tessellation_control`
|
||
* `compute`
|
||
* `multi`
|
||
|
||
The compute pipeline can only contain compute shaders. The graphics pipeline
|
||
can not contain compute shaders, and must contain a vertex shader and a fragment
|
||
shader.
|
||
|
||
The provided `multi` shader can only be used with `SPIRV-ASM` and `SPIRV-HEX`
|
||
and allows for providing multiple shaders in a single module (so the `vertex`
|
||
and `fragment` shaders can be provided together.)
|
||
|
||
Note, `SPIRV-ASM` and `SPIRV-HEX` can also be used with each of the other shader
|
||
types, but in that case must only provide a single shader type in the module.
|
||
|
||
#### Shader Format
|
||
* `GLSL` (with glslang)
|
||
* `HLSL` (with dxc or glslang if dxc disabled)
|
||
* `SPIRV-ASM` (with spirv-as; specifying `TARGET_ENV` is _highly recommended_
|
||
in this case, as explained below)
|
||
* `SPIRV-HEX` (decoded straight to SPIR-V)
|
||
* `OPENCL-C` (with clspv)
|
||
|
||
### Target environment
|
||
|
||
Specifying `TARGET_ENV` is optional and can be used to select a target
|
||
SPIR-V environment. For example:
|
||
|
||
* `spv1.0`
|
||
* `spv1.5`
|
||
* `vulkan1.0`
|
||
* `vulkan1.2`
|
||
|
||
Check the help text of the corresponding tool (e.g. spirv-as, glslangValidator)
|
||
for the full list. The `SPIRV-HEX` shader format is not affected by the target
|
||
environment.
|
||
|
||
The specified target environment for the shader overrides the default (`spv1.0`)
|
||
or the one specified on the command line.
|
||
|
||
Specifying the target environment when using the `SPIRV-ASM` shader format
|
||
is _highly recommended_, otherwise the SPIR-V version of the final SPIR-V binary
|
||
shader passed to the graphics device might not be what you expect.
|
||
Typically, SPIR-V assembly text will contain a comment near the beginning similar
|
||
to `; Version: 1.0` but this is _ignored_ by the spirv-as assembler.
|
||
Thus, you should specify the equivalent target environment (e.g. `spv1.0`)
|
||
in the `SHADER` command.
|
||
|
||
Specifying the target environment for other shader formats depends on whether
|
||
you want to vary the final SPIR-V shader binary based on the target environment
|
||
specified on the command line. For example, you could write one AmberScript file
|
||
that contains a GLSL shader without specifying a target environment.
|
||
You could then run the AmberScript file several times with different
|
||
target environments specified on the command line
|
||
(`spv1.0`, `spv1.1`, `spv1.2`, etc.) to test the different SPIR-V shader variants.
|
||
|
||
### Buffers
|
||
|
||
An AmberScript buffer represents a set of contiguous bits. This can be used for
|
||
either image buffers or, what the target API would refer to as a buffer.
|
||
|
||
#### Data Types
|
||
* `int8`
|
||
* `int16`
|
||
* `int32`
|
||
* `int64`
|
||
* `uint8`
|
||
* `uint16`
|
||
* `uint32`
|
||
* `uint64`
|
||
* `float16`
|
||
* `float`
|
||
* `double`
|
||
* vec[2,3,4]{type}
|
||
* mat[2,3,4]x[2,3,4]{type} (mat<columns>x<rows>)
|
||
* Any of the `Image Formats` listed below.
|
||
* For any of the non-Image Formats types above appending '[]' will treat the
|
||
data as an array. e.g. int8[], vec2<float>[]
|
||
|
||
Sized arrays and structures are not currently representable.
|
||
|
||
```groovy
|
||
# Filling the buffer with a given initializer. Initializer data must be
|
||
# of |type|. Buffers are STD430 by default.
|
||
BUFFER {name} DATA_TYPE {type} {STD140 | STD430} {initializer}
|
||
|
||
# Defines a buffer which is filled with data as specified by the `initializer`.
|
||
BUFFER {name} DATA_TYPE {type} {STD140 | STD430} SIZE _size_in_items_ \
|
||
{initializer}
|
||
|
||
# Deprecated
|
||
# Defines a buffer with width and height and filled by data as specified by the
|
||
# `initializer`.
|
||
BUFFER {name} DATA_TYPE {type} {STD140 | STD430} WIDTH {w} HEIGHT {h} \
|
||
{initializer}
|
||
|
||
# Defines a buffer which is filled with binary data from a file specified
|
||
# by `FILE`.
|
||
BUFFER {name} DATA_TYPE {type} {STD140 | STD430} SIZE _size_in_items_ \
|
||
FILE BINARY {file_name}
|
||
|
||
# Defines a buffer which is filled with text data parsed from a file specified
|
||
# by `FILE`.
|
||
BUFFER {name} DATA_TYPE {type} {STD140 | STD430} SIZE _size_in_items_ \
|
||
FILE TEXT {file_name}
|
||
|
||
# Creates a buffer which will store the given `FORMAT` of data. These
|
||
# buffers are used as image and depth buffers in the `PIPELINE` commands.
|
||
# The buffer will be sized based on the `RENDER_SIZE` of the `PIPELINE`.
|
||
# For multisampled images use value greater than one for `SAMPLES`. Allowed
|
||
# sample counts are 1, 2, 4, 8, 16, 32, and 64. Note that Amber doesn't
|
||
# preserve multisampled images across pipelines.
|
||
BUFFER {name} FORMAT {format_string} \
|
||
[ MIP_LEVELS _mip_levels_ (default 1) ] \
|
||
[ SAMPLES _samples_ (default 1) ]
|
||
|
||
# Load buffer data from a PNG image with file name specified by `FILE`.
|
||
# The file path is relative to the script file being run. Format specified
|
||
# by `FORMAT` must match the image format.
|
||
BUFFER {name} FORMAT {format_string} FILE PNG {file_name.png}
|
||
```
|
||
|
||
#### Images
|
||
|
||
An AmberScript image is a specialized buffer that specifies image-specific
|
||
attributes.
|
||
|
||
##### Dimensionality
|
||
* `DIM_1D` -- A 1-dimensional image
|
||
* `DIM_2D` -- A 2-dimensional image
|
||
* `DIM_3D` -- A 3-dimensional image
|
||
|
||
```groovy
|
||
# Specify an image buffer with a format. HEIGHT is necessary for DIM_2D and
|
||
# DIM_3D. DEPTH is necessary for DIM_3D.
|
||
IMAGE {name} FORMAT {format_string} [ MIP_LEVELS _mip_levels_ (default 1) ] \
|
||
[ SAMPLES _samples_ (default 1) ] \
|
||
{dimensionality} \
|
||
WIDTH {w} [ HEIGHT {h} [ DEPTH {d} ] ] \
|
||
{initializer}
|
||
|
||
# Specify an image buffer with a data type. HEIGHT is necessary for DIM_2D and
|
||
# DIM_3D. DEPTH is necessary for DIM_3D.
|
||
IMAGE {name} DATA_TYPE {type} {dimensionality} \
|
||
WIDTH {w} [ HEIGHT {h} [ DEPTH {d} ] ] \
|
||
{intializer}
|
||
```
|
||
|
||
#### Buffer Initializers
|
||
|
||
```groovy
|
||
# Filling the buffer with a given set of data. The values must be
|
||
# of the correct type. The data can be provided as the type or as a hex
|
||
# value.
|
||
DATA
|
||
_value_+
|
||
END
|
||
|
||
```groovy
|
||
# Fill the buffer with a single value.
|
||
FILL _value_
|
||
|
||
# Fill the buffer with an increasing value from |start| increasing by |inc|.
|
||
# Floating point data uses floating point addition to generate increasing
|
||
# values. Likewise, integer data uses integer addition to generate increasing
|
||
# values.
|
||
SERIES_FROM _start_ INC_BY _inc_
|
||
```
|
||
|
||
#### Buffer Copy
|
||
|
||
```groovy
|
||
# Copies all data, values and memory from |buffer_from| to |buffer_to|.
|
||
# Both buffers must be declared, and of the same data type.
|
||
# Buffers used as copy destination can be used only as copy destination, and as
|
||
# argument to an EXPECT command.
|
||
COPY {buffer_from} TO {buffer_to}
|
||
```
|
||
|
||
### Samplers
|
||
|
||
Samplers are used for sampling buffers that are bound to a pipeline as
|
||
sampled image or combined image sampler.
|
||
|
||
#### Filter types
|
||
* `nearest`
|
||
* `linear`
|
||
|
||
#### Address modes
|
||
* `repeat`
|
||
* `mirrored_repeat`
|
||
* `clamp_to_edge`
|
||
* `clamp_to_border`
|
||
* `mirrored_clamp_to_edge`
|
||
|
||
#### Border colors
|
||
* `float_transparent_black`
|
||
* `int_transparent_black`
|
||
* `float_opaque_black`
|
||
* `int_opaque_black`
|
||
* `float_opaque_white`
|
||
* `int_opaque_white`
|
||
|
||
```groovy
|
||
|
||
# Creates a sampler with |name|.
|
||
SAMPLER {name} \
|
||
[ MAG_FILTER {filter_type} (default nearest) ] \
|
||
[ MIN_FILTER {filter_type} (default nearest) ] \
|
||
[ ADDRESS_MODE_U {address_mode} (default repeat) ] \
|
||
[ ADDRESS_MODE_V {address_mode} (default repeat) ] \
|
||
[ ADDRESS_MODE_W {address_mode} (default repeat) ] \
|
||
[ BORDER_COLOR {border_color} (default float_transparent_black) ] \
|
||
[ MIN_LOD _val_ (default 0.0) ] \
|
||
[ MAX_LOD _val_ (default 1.0) ] \
|
||
[ NORMALIZED_COORDS | UNNORMALIZED_COORDS (default NORMALIZED_COORDS) ]
|
||
```
|
||
|
||
Note: unnormalized coordinates will override MIN\_LOD and MAX\_LOD to 0.0.
|
||
|
||
#### OpenCL Literal Samplers
|
||
|
||
Literal constant samplers defined in the OpenCL program are automatically
|
||
generated and bound to the pipeline in Amber.
|
||
|
||
Note: currently the border color is always transparent black.
|
||
|
||
Note: the addressing mode is used for all coordinates currently. Arrayed images
|
||
should use `clamp_to_edge` for the array index.
|
||
|
||
### Pipelines
|
||
|
||
#### Pipeline type
|
||
* `compute`
|
||
* `graphics`
|
||
|
||
```groovy
|
||
# The PIPELINE command creates a pipeline. This can be either compute or
|
||
# graphics. Shaders are attached to the pipeline at pipeline creation time.
|
||
PIPELINE {pipeline_type} {pipeline_name}
|
||
...
|
||
END
|
||
|
||
# Create a pipeline and inherit from a previously declared pipeline.
|
||
DERIVE_PIPELINE {pipeline_name} FROM {parent_pipeline}
|
||
...
|
||
END
|
||
```
|
||
|
||
### Pipeline Content
|
||
|
||
The following commands are all specified within the `PIPELINE` command.
|
||
```groovy
|
||
# Attach the shader provided by |name_of_shader| to the pipeline with an
|
||
# entry point name of |name|. The provided shader for ATTACH must _not_ be
|
||
# a 'multi' shader.
|
||
ATTACH {name_of_shader} \
|
||
[ ENTRY_POINT {name} (default "main") ]
|
||
|
||
# Attach a 'multi' shader to the pipeline of |shader_type| and use the entry
|
||
# point with |name|. The provided shader _must_ be a 'multi' shader.
|
||
ATTACH {name_of_multi_shader} TYPE {shader_type} ENTRY_POINT {name}
|
||
|
||
# Attach specialized shader. Specialization can be specified multiple times.
|
||
# Specialization values must be a 32-bit type. Shader type and entry point
|
||
# must be specified prior to specializing the shader.
|
||
ATTACH {name_of_shader} SPECIALIZE _id_ AS uint32 _value_
|
||
ATTACH {name_of_shader} \
|
||
SPECIALIZE _id_ AS uint32 _value_ \
|
||
SPECIALIZE _id_ AS float _value_
|
||
```
|
||
|
||
```groovy
|
||
# Set the SPIRV-Tools optimization passes to use for a given shader. The
|
||
# default is to run no optimization passes.
|
||
SHADER_OPTIMIZATION {shader_name}
|
||
{optimization_name}+
|
||
END
|
||
```
|
||
|
||
```groovy
|
||
# Set the compile options used to compile the given shader. Options are parsed
|
||
# the same as on the command line. Currently, only supported for OPENCL-C shaders.
|
||
COMPILE_OPTIONS {shader_name}
|
||
{option}+
|
||
END
|
||
```
|
||
|
||
```groovy
|
||
# Set the polygon mode used for all drawing with the pipeline.
|
||
# |mode| is fill, line, or point and it defaults to fill.
|
||
POLYGON_MODE {mode}
|
||
```
|
||
|
||
```groovy
|
||
# Set the number of patch control points used by tessellation. The default value is 3.
|
||
PATCH_CONTROL_POINTS {control_points}
|
||
```
|
||
|
||
#### Compare operations
|
||
* `never`
|
||
* `less`
|
||
* `equal`
|
||
* `less_or_equal`
|
||
* `greater`
|
||
* `not_equal`
|
||
* `greater_or_equal`
|
||
* `always`
|
||
|
||
```groovy
|
||
# Set depth test settings. All enable options are specified with keywords on and off.
|
||
# BOUNDS and BIAS values are specified with decimal numbers. |compare_op| is selected
|
||
# from the list of compare operations above.
|
||
DEPTH
|
||
TEST {test_enable}
|
||
WRITE {write_enable}
|
||
COMPARE_OP {compare_op}
|
||
CLAMP {clamp_enable}
|
||
BOUNDS min {bound_min} max {bounds_max}
|
||
BIAS constant {bias_constant} clamp {bias_clamp} slope {bias_slope}
|
||
END
|
||
```
|
||
|
||
#### Stencil operations
|
||
* `keep`
|
||
* `replace`
|
||
* `increment_and_clamp`
|
||
* `decrement_and_clamp`
|
||
* `invert`
|
||
* `increment_and_wrap`
|
||
* `decrement_and_wrap`
|
||
|
||
```groovy
|
||
# Set stencil test settings. |face| can be front, back, or front_and_back.
|
||
# |test_enable| is either on or off and affects both faces. |fail_op|, |pass_op|,
|
||
# and |depth_fail_op| are selected from the stencil operations table above,
|
||
# and |compare_op| from the compare operations table. |compare_mask|, |write_mask|,
|
||
# and |reference| are 8bit unsigned integer values (range 0..255).
|
||
STENCIL {face}
|
||
TEST {test_enable}
|
||
FAIL_OP {fail_op}
|
||
PASS_OP {pass_op}
|
||
DEPTH_FAIL_OP {depth_fail_op}
|
||
COMPARE_OP {compare_op}
|
||
COMPARE_MASK {compare_mask}
|
||
WRITE_MASK {write_mask}
|
||
REFERENCE {reference}
|
||
END
|
||
```
|
||
|
||
#### Blend factors
|
||
* `zero`
|
||
* `one`
|
||
* `src_color`
|
||
* `one_minus_src_color`
|
||
* `dst_color`
|
||
* `one_minus_dst_color`
|
||
* `src_alpha`
|
||
* `one_minus_src_alpha`
|
||
* `dst_alpha`
|
||
* `one_minus_dst_alpha`
|
||
* `constant_color`
|
||
* `one_minus_constant_color`
|
||
* `constant_alpha`
|
||
* `one_minus_constant_alpha`
|
||
* `src_alpha_saturate`
|
||
* `src1_color`
|
||
* `one_minus_src1_color`
|
||
* `src1_alpha`
|
||
* `one_minus_src1_alpha`
|
||
|
||
#### Blend operations
|
||
* `add`
|
||
* `substract`
|
||
* `reverse_substract`
|
||
* `min`
|
||
* `max`
|
||
|
||
The following operations also require VK_EXT_blend_operation_advanced
|
||
when using a Vulkan backend.
|
||
* `zero`
|
||
* `src`
|
||
* `dst`
|
||
* `src_over`
|
||
* `dst_over`
|
||
* `src_in`
|
||
* `dst_in`
|
||
* `src_out`
|
||
* `dst_out`
|
||
* `src_atop`
|
||
* `dst_atop`
|
||
* `xor`
|
||
* `multiply`
|
||
* `screen`
|
||
* `overlay`
|
||
* `darken`
|
||
* `lighten`
|
||
* `color_dodge`
|
||
* `color_burn`
|
||
* `hard_light`
|
||
* `soft_light`
|
||
* `difference`
|
||
* `exclusion`
|
||
* `invert`
|
||
* `invert_rgb`
|
||
* `linear_dodge`
|
||
* `linear_burn`
|
||
* `vivid_light`
|
||
* `linear_light`
|
||
* `pin_light`
|
||
* `hard_mix`
|
||
* `hsl_hue`
|
||
* `hsl_saturation`
|
||
* `hsl_color`
|
||
* `hsl_luminosity`
|
||
* `plus`
|
||
* `plus_clamped`
|
||
* `plus_clamped_alpha`
|
||
* `plus_darker`
|
||
* `minus`
|
||
* `minus_clamped`
|
||
* `contrast`
|
||
* `invert_org`
|
||
* `red`
|
||
* `green`
|
||
* `blue`
|
||
|
||
```groovy
|
||
# Enable alpha blending and set blend factors and operations. Available
|
||
# blend factors and operations are listed above.
|
||
BLEND
|
||
SRC_COLOR_FACTOR {src_color_factor}
|
||
DST_COLOR_FACTOR {dst_color_factor}
|
||
COLOR_OP {color_op}
|
||
SRC_ALPHA_FACTOR {src_alpha_factor}
|
||
DST_ALPHA_FACTOR {dst_alpha_factor}
|
||
ALPHA_OP {alpha_op}
|
||
END
|
||
```
|
||
|
||
```groovy
|
||
# Set the size of the render buffers. |width| and |height| are integers and
|
||
# default to 250x250.
|
||
FRAMEBUFFER_SIZE _width_ _height_
|
||
```
|
||
|
||
```groovy
|
||
# Set the viewport size. If no viewport is provided then it defaults to the
|
||
# whole framebuffer size. Depth range defaults to 0 to 1.
|
||
VIEWPORT {x} {y} SIZE {width} {height} [MIN_DEPTH {mind}] [MAX_DEPTH {maxd}]
|
||
```
|
||
|
||
```groovy
|
||
# Set subgroup size control setting. Require that subgroups must be launched
|
||
# with all invocations active for given shader. Allow SubgroupSize to vary
|
||
# for given shader. Require a specific SubgroupSize the for given shader.
|
||
# |fully_populated_enable| and |varying_size_enable| can be on or off.
|
||
# |subgroup_size| can be set one of the values below:
|
||
# - a power-of-two integer that _must_ be greater or equal to minSubgroupSize
|
||
# and be less than or equal to maxSubgroupSize
|
||
# - MIN to set the required subgroup size to the minSubgroupSize
|
||
# - MAX to set the required subgroup size to the maxSubgroupSize
|
||
SUBGROUP {name_of_shader}
|
||
FULLY_POPULATED {fully_populated_enable}
|
||
VARYING_SIZE {varying_size_enable}
|
||
REQUIRED_SIZE {subgroup_size}
|
||
END
|
||
```
|
||
|
||
### Pipeline Buffers
|
||
|
||
#### Buffer Types
|
||
* `uniform`
|
||
* `storage`
|
||
* `uniform_dynamic`
|
||
* `storage_dynamic`
|
||
* `uniform_texel_buffer`
|
||
* `storage_texel_buffer`
|
||
|
||
TODO(dsinclair): Sync the BufferTypes with the list of Vulkan Descriptor types.
|
||
|
||
A `pipeline` can have buffers or samplers bound. This includes buffers to
|
||
contain image attachment content, depth/stencil content, uniform buffers, etc.
|
||
|
||
```groovy
|
||
# Attach |buffer_name| as an output color attachment at location |idx|.
|
||
# The provided buffer must be a `FORMAT` buffer. If no color attachments are
|
||
# provided a single attachment with format `B8G8R8A8_UNORM` will be created
|
||
# for graphics pipelines. The MIP level will have a base of |level|.
|
||
BIND BUFFER {buffer_name} AS color LOCATION _idx_ \
|
||
[ BASE_MIP_LEVEL _level_ (default 0) ]
|
||
|
||
# Attach |buffer_name| as the depth/stencil buffer. The provided buffer must
|
||
# be a `FORMAT` buffer. If no depth/stencil buffer is specified a default
|
||
# buffer of format `D32_SFLOAT_S8_UINT` will be created for graphics
|
||
# pipelines.
|
||
BIND BUFFER {buffer_name} AS depth_stencil
|
||
|
||
# Attach |buffer_name| as a multisample resolve target. The order of resolve
|
||
# target images match with the order of color attachments that have more than
|
||
# one sample.
|
||
BIND BUFFER {buffer_name} AS resolve
|
||
|
||
# Attach |buffer_name| as the push_constant buffer. There can be only one
|
||
# push constant buffer attached to a pipeline.
|
||
BIND BUFFER {buffer_name} AS push_constant
|
||
|
||
# Bind OpenCL argument buffer by name. Specifying the buffer type is optional.
|
||
# Amber will set the type as appropriate for the argument buffer. All uses
|
||
# of the buffer must have a consistent |buffer_type| across all pipelines.
|
||
BIND BUFFER {buffer_name} [ AS {buffer_type} (default computed)] \
|
||
KERNEL ARG_NAME _name_
|
||
|
||
# Bind OpenCL argument buffer by argument ordinal. Arguments use 0-based
|
||
# numbering. Specifying the buffer type is optional. Amber will set the
|
||
# type as appropriate for the argument buffer. All uses of the buffer
|
||
# must have a consistent |buffer_type| across all pipelines.
|
||
BIND BUFFER {buffer_name} [ AS {buffer_type} (default computed)] \
|
||
KERNEL ARG_NUMBER _number_
|
||
|
||
# Bind OpenCL argument sampler by argument name.
|
||
BIND SAMPLER {sampler_name} KERNEL ARG_NAME _name_
|
||
|
||
# Bind OpenCL argument sampler by argument ordinal. Arguments use 0-based
|
||
# numbering.
|
||
BIND SAMPLER {sampler_name} KERNEL ARG_NUMBER _number_
|
||
```
|
||
|
||
All BIND BUFFER and BIND SAMPLER commands below define a descriptor set and binding ID.
|
||
These commands can be replaced with BIND BUFFER_ARRAY and BIND SAMPLER_ARRAY commands.
|
||
In these cases multiple buffer or sampler names need to be provided, separated by spaces.
|
||
This creates a descriptor array of buffers or samplers bound to the same descriptor set
|
||
and binding ID. An array of dynamic offsets should be provided via `OFFSET offset1 offset2 ...`
|
||
when using dynamic buffers with BUFFER_ARRAY. Optional descriptor binding offset(s) and range(s)
|
||
can be defined via `DESCRIPTOR_OFFSET offset1 offset2 ...` and
|
||
`DESCRIPTOR_RANGE range1 range2 ...` when using uniform or storage buffers. Offsets and
|
||
ranges can be used also with dynamic buffers.
|
||
```groovy
|
||
# Bind the buffer of the given |buffer_type| at the given descriptor set
|
||
# and binding. The buffer will use a byte offset |descriptor_offset|
|
||
# with range |range|.
|
||
BIND {BUFFER | BUFFER_ARRAY} {buffer_name} AS {buffer_type} DESCRIPTOR_SET _id_ \
|
||
BINDING _id_ [ DESCRIPTOR_OFFSET _descriptor_offset_ (default 0) ] \
|
||
[ DESCRIPTOR_RANGE _range_ (default -1 == VK_WHOLE_SIZE) ]
|
||
|
||
# Attach |buffer_name| as a storage image. The MIP level will have a base
|
||
# value of |level|.
|
||
BIND {BUFFER | BUFFER_ARRAY} {buffer_name} AS storage_image \
|
||
DESCRIPTOR_SET _id_ BINDING _id_ [ BASE_MIP_LEVEL _level_ (default 0) ]
|
||
|
||
# Attach |buffer_name| as a sampled image. The MIP level will have a base
|
||
# value of |level|.
|
||
BIND {BUFFER | BUFFER_ARRAY} {buffer_name} AS sampled_image \
|
||
DESCRIPTOR_SET _id_ BINDING _id_ [ BASE_MIP_LEVEL _level_ (default 0) ]
|
||
|
||
# Attach |buffer_name| as a combined image sampler. A sampler |sampler_name|
|
||
# must also be specified. The MIP level will have a base value of 0.
|
||
BIND {BUFFER | BUFFER_ARRAY} {buffer_name} AS combined_image_sampler SAMPLER {sampler_name} \
|
||
DESCRIPTOR_SET _id_ BINDING _id_ [ BASE_MIP_LEVEL _level_ (default 0) ]
|
||
|
||
# Bind the sampler at the given descriptor set and binding.
|
||
BIND {SAMPLER | SAMPLER_ARRAY} {sampler_name} DESCRIPTOR_SET _id_ BINDING _id_
|
||
|
||
# Bind |buffer_name| as dynamic uniform/storage buffer at the given descriptor set
|
||
# and binding. The buffer will use a byte offset |offset| + |descriptor_offset|
|
||
# with range |range|.
|
||
BIND {BUFFER | BUFFER_ARRAY} {buffer_name} AS {uniform_dynamic | storage_dynamic} \
|
||
DESCRIPTOR_SET _id_ BINDING _id_ OFFSET _offset_ \
|
||
[ DESCRIPTOR_OFFSET _descriptor_offset_ (default 0) ] \
|
||
[ DESCRIPTOR_RANGE _range_ (default -1 == VK_WHOLE_SIZE) ]
|
||
```
|
||
|
||
```groovy
|
||
# Set |buffer_name| as the vertex data at location |val|. RATE defines the
|
||
# input rate for vertex attribute reading. OFFSET sets the byte offset for the
|
||
# vertex data within the buffer |buffer_name|, which by default is 0. FORMAT
|
||
# sets the vertex buffer format, which by default is the format of the buffer
|
||
# |buffer_name|. STRIDE sets the byte stride, which by default is the stride
|
||
# of the format (set explicitly via FORMAT or from the format of the buffer
|
||
# |buffer_name|).
|
||
VERTEX_DATA {buffer_name} LOCATION _val_ [ RATE { vertex | instance } (default vertex) ] \
|
||
[ FORMAT {format} ] [ OFFSET {offset} ] [ STRIDE {stride} ]
|
||
|
||
# Set |buffer_name| as the index data to use for `INDEXED` draw commands.
|
||
INDEX_DATA {buffer_name}
|
||
```
|
||
|
||
#### OpenCL Plain-Old-Data Arguments
|
||
OpenCL kernels can have plain-old-data (pod or pod_ubo in the desriptor map)
|
||
arguments set their data via this command. Amber will generate the appropriate
|
||
buffers for the pipeline populated with the specified data.
|
||
|
||
```groovy
|
||
# Set argument |name| to |data_type| with value |val|.
|
||
SET KERNEL ARG_NAME _name_ AS {data_type} _val_
|
||
|
||
# Set argument |number| to |data_type| with value |val|.
|
||
# Arguments use 0-based numbering.
|
||
SET KERNEL ARG_NUMBER _number_ AS {data_type} _val_
|
||
```
|
||
|
||
#### Topologies
|
||
* `POINT_LIST`
|
||
* `LINE_LIST`
|
||
* `LINE_LIST_WITH_ADJACENCY`
|
||
* `LINE_STRIP`
|
||
* `LINE_STRIP_WITH_ADJACENCY`
|
||
* `TRIANGLE_LIST`
|
||
* `TRIANGLE_LIST_WITH_ADJACENCY`
|
||
* `TRIANGLE_STRIP`
|
||
* `TRIANGLE_STRIP_WITH_ADJACENCY`
|
||
* `TRIANGLE_fan`
|
||
* `PATCH_LIST`
|
||
|
||
### Run a pipeline.
|
||
|
||
When running a `DRAW_ARRAY` command, you must attach the vertex data to the
|
||
`PIPELINE` with the `VERTEX_DATA` command.
|
||
|
||
To run an indexed draw, attach the index data to the `PIPELINE` with an
|
||
`INDEX_DATA` command.
|
||
|
||
For the commands which take a `START_IDX` and a `COUNT` they can be left off the
|
||
command (although, `START_IDX` is required if `COUNT` is provided). The default
|
||
value for `START_IDX` is 0. The default value for `COUNT` is the item count of
|
||
vertex buffer minus the `START_IDX`. The same applies to `START_INSTANCE`
|
||
(default 0) and `INSTANCE_COUNT` (default 1).
|
||
|
||
```groovy
|
||
# Run the given |pipeline_name| which must be a `compute` pipeline. The
|
||
# pipeline will be run with the given number of workgroups in the |x|, |y|, |z|
|
||
# dimensions. Each of the x, y and z values must be a uint32.
|
||
RUN {pipeline_name} _x_ _y_ _z_
|
||
```
|
||
|
||
```groovy
|
||
# Run the given |pipeline_name| which must be a `graphics` pipeline. The
|
||
# rectangle at |x|, |y|, |width|x|height| will be rendered. Ignores VERTEX_DATA
|
||
# and INDEX_DATA on the given pipeline.
|
||
RUN {pipeline_name} \
|
||
DRAW_RECT POS _x_in_pixels_ _y_in_pixels_ \
|
||
SIZE _width_in_pixels_ _height_in_pixels_
|
||
```
|
||
|
||
```groovy
|
||
# Run the given |pipeline_name| which must be a `graphics` pipeline. The
|
||
# grid at |x|, |y|, |width|x|height|, |columns|x|rows| will be rendered.
|
||
# Ignores VERTEX_DATA and INDEX_DATA on the given pipeline.
|
||
# For columns, rows of (5, 4) a total of 5*4=20 rectangles will be drawn.
|
||
RUN {pipeline_name} \
|
||
DRAW_GRID POS _x_in_pixels_ _y_in_pixels_ \
|
||
SIZE _width_in_pixels_ _height_in_pixels_ \
|
||
CELLS _columns_of_cells_ _rows_of_cells_
|
||
```
|
||
|
||
```groovy
|
||
# Run the |pipeline_name| which must be a `graphics` pipeline. The vertex
|
||
# data must be attached to the pipeline.
|
||
|
||
# A start index of |value| will be used and the count of |count_value| items
|
||
# will be processed. The draw is instanced if |inst_count_value| is greater
|
||
# than one. In case of instanced draw |inst_value| controls the starting
|
||
# instance ID.
|
||
RUN {pipeline_name} DRAW_ARRAY AS {topology} \
|
||
[ START_IDX _value_ (default 0) ] \
|
||
[ COUNT _count_value_ (default vertex_buffer size - start_idx) ] \
|
||
[ START_INSTANCE _inst_value_ (default 0) ] \
|
||
[ INSTANCE_COUNT _inst_count_value_ (default 1) ]
|
||
```
|
||
|
||
```groovy
|
||
# Run the |pipeline_name| which must be a `graphics` pipeline. The vertex
|
||
# data and index data must be attached to the pipeline. The vertices will be
|
||
# drawn using the given |topology|.
|
||
#
|
||
# A start index of |value| will be used and the count of |count_value| items
|
||
# will be processed. The draw is instanced if |inst_count_value| is greater
|
||
# than one. In case of instanced draw |inst_value| controls the starting
|
||
# instance ID.
|
||
RUN {pipeline_name} DRAW_ARRAY AS {topology} INDEXED \
|
||
[ START_IDX _value_ (default 0) ] \
|
||
[ COUNT _count_value_ (default index_buffer size - start_idx) ] \
|
||
[ START_INSTANCE _inst_value_ (default 0) ] \
|
||
[ INSTANCE_COUNT _inst_count_value_ (default 1) ]
|
||
```
|
||
|
||
### Repeating commands
|
||
|
||
```groovy
|
||
# It is sometimes useful to run a given draw command multiple times. This can be
|
||
# to detect deterministic rendering or other features.
|
||
REPEAT {count}
|
||
{command}+
|
||
END
|
||
```
|
||
|
||
The commands which can be used inside a `REPEAT` block are:
|
||
* `CLEAR`
|
||
* `CLEAR_COLOR`
|
||
* `CLEAR_DEPTH`
|
||
* `CLEAR_STENCIL`
|
||
* `COPY`
|
||
* `EXPECT`
|
||
* `RUN`
|
||
|
||
### Commands
|
||
|
||
```groovy
|
||
# Sets the clear color to use for |pipeline| which must be a graphics
|
||
# pipeline. The colors are integers from 0 - 255. Defaults to (0, 0, 0, 0)
|
||
CLEAR_COLOR {pipeline} _r (0 - 255)_ _g (0 - 255)_ _b (0 - 255)_ _a (0 - 255)_
|
||
|
||
# Sets the depth clear value to use for |pipeline| which must be a graphics
|
||
# pipeline. |value| must be a decimal number.
|
||
CLEAR_DEPTH {pipeline} _value_
|
||
|
||
# Sets the stencil clear value to use for |pipeline| which must be a graphics
|
||
# pipeline. |value| must be an integer from 0 - 255.
|
||
CLEAR_STENCIL {pipeline} _value_
|
||
|
||
# Instructs the |pipeline| which must be a graphics pipeline to execute the
|
||
# clear command.
|
||
CLEAR {pipeline}
|
||
```
|
||
|
||
### Expectations
|
||
|
||
#### Comparators
|
||
* `EQ`
|
||
* `NE`
|
||
* `LT`
|
||
* `LE`
|
||
* `GT`
|
||
* `GE`
|
||
* `EQ_RGB`
|
||
* `EQ_RGBA`
|
||
* `EQ_BUFFER`
|
||
* `RMSE_BUFFER`
|
||
* `EQ_HISTOGRAM_EMD_BUFFER`
|
||
|
||
```groovy
|
||
# Checks that |buffer_name| at |x| has the given |value|s when compared
|
||
# with the given |comparator|.
|
||
EXPECT {buffer_name} IDX _x_ {comparator} _value_+
|
||
|
||
# Checks that |buffer_name| at |x| has values within |tolerance| of |value|
|
||
# The |tolerance| can be specified as 1-4 float values separated by spaces.
|
||
# The tolerances may be given as a percentage by placing a '%' symbol after
|
||
# the value. If less tolerance values are provided then are needed for a given
|
||
# data component the default tolerance will be applied.
|
||
EXPECT {buffer_name} IDX _x_ TOLERANCE _tolerance_{1,4} EQ _value_+
|
||
|
||
# Checks that |buffer_name| at |x|, |y| for |width|x|height| pixels has the
|
||
# given |r|, |g|, |b| values. Each r, g, b value is an integer from 0-255.
|
||
EXPECT {buffer_name} IDX _x_in_pixels_ _y_in_pixels_ \
|
||
SIZE _width_in_pixels_ _height_in_pixels_ \
|
||
EQ_RGB _r (0 - 255)_ _g (0 - 255)_ _b (0 - 255)_
|
||
|
||
# Checks that |buffer_name| at |x|, |y| for |width|x|height| pixels has the
|
||
# given |r|, |g|, |b|, |a| values. Each r, g, b, a value is an integer
|
||
# from 0-255.
|
||
EXPECT {buffer_name} IDX _x_in_pixels_ _y_in_pixels_ \
|
||
SIZE _width_in_pixels_ _height_in_pixels_ \
|
||
EQ_RGBA _r (0 - 255)_ _g (0 - 255)_ _b (0 - 255)_ _a (0 - 255)_
|
||
|
||
# Checks that |buffer_1| contents are equal to those of |buffer_2|
|
||
EXPECT {buffer_1} EQ_BUFFER {buffer_2}
|
||
|
||
# Checks that the Root Mean Square Error when comparing |buffer_1| to
|
||
# |buffer_2| is less than or equal to |tolerance|. Note, |tolerance| is a
|
||
# unit-less number.
|
||
EXPECT {buffer_1} RMSE_BUFFER {buffer_2} TOLERANCE _value_
|
||
|
||
# Checks that the Earth Mover's Distance when comparing histograms of
|
||
# |buffer_1| to |buffer_2| is less than or equal to |tolerance|.
|
||
# Note, |tolerance| is a unit-less number.
|
||
EXPECT {buffer_1} EQ_HISTOGRAM_EMD_BUFFER {buffer_2} TOLERANCE _value_
|
||
```
|
||
|
||
## Examples
|
||
|
||
### Compute Shader
|
||
|
||
```groovy
|
||
#!amber
|
||
# Simple amber compute shader.
|
||
|
||
SHADER compute kComputeShader GLSL
|
||
#version 450
|
||
|
||
layout(binding = 3) buffer block {
|
||
vec2 values[];
|
||
};
|
||
|
||
void main() {
|
||
values[gl_WorkGroupID.x + gl_WorkGroupID.y * gl_NumWorkGroups.x] =
|
||
gl_WorkGroupID.xy;
|
||
}
|
||
END # shader
|
||
|
||
BUFFER kComputeBuffer DATA_TYPE vec2<int32> SIZE 524288 FILL 0
|
||
|
||
PIPELINE compute kComputePipeline
|
||
ATTACH kComputeShader
|
||
BIND BUFFER kComputeBuffer AS storage DESCRIPTOR_SET 0 BINDING 3
|
||
END # pipeline
|
||
|
||
RUN kComputePipeline 256 256 1
|
||
|
||
# Four corners
|
||
EXPECT kComputeBuffer IDX 0 EQ 0 0
|
||
EXPECT kComputeBuffer IDX 2040 EQ 255 0
|
||
EXPECT kComputeBuffer IDX 522240 EQ 0 255
|
||
EXPECT kComputeBuffer IDX 524280 EQ 255 255
|
||
|
||
# Center
|
||
EXPECT kComputeBuffer IDX 263168 EQ 128 128
|
||
```
|
||
|
||
### Entry Points
|
||
|
||
```groovy
|
||
#!amber
|
||
|
||
SHADER vertex kVertexShader PASSTHROUGH
|
||
|
||
SHADER fragment kFragmentShader SPIRV-ASM
|
||
OpCapability Shader
|
||
%1 = OpExtInstImport "GLSL.std.450"
|
||
OpMemoryModel Logical GLSL450
|
||
|
||
; two entrypoints
|
||
OpEntryPoint Fragment %red "red" %color
|
||
OpEntryPoint Fragment %green "green" %color
|
||
|
||
OpExecutionMode %red OriginUpperLeft
|
||
OpExecutionMode %green OriginUpperLeft
|
||
OpSource GLSL 430
|
||
OpName %red "red"
|
||
OpDecorate %color Location 0
|
||
%void = OpTypeVoid
|
||
%3 = OpTypeFunction %void
|
||
%float = OpTypeFloat 32
|
||
%v4float = OpTypeVector %float 4
|
||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||
%color = OpVariable %_ptr_Output_v4float Output
|
||
%float_1 = OpConstant %float 1
|
||
%float_0 = OpConstant %float 0
|
||
%red_color = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
|
||
%green_color = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
|
||
|
||
; this entrypoint outputs a red color
|
||
%red = OpFunction %void None %3
|
||
%5 = OpLabel
|
||
OpStore %color %red_color
|
||
OpReturn
|
||
OpFunctionEnd
|
||
|
||
; this entrypoint outputs a green color
|
||
%green = OpFunction %void None %3
|
||
%6 = OpLabel
|
||
OpStore %color %green_color
|
||
OpReturn
|
||
OpFunctionEnd
|
||
END # shader
|
||
|
||
BUFFER kImgBuffer FORMAT R8G8B8A8_UINT
|
||
|
||
PIPELINE graphics kRedPipeline
|
||
ATTACH kVertexShader ENTRY_POINT main
|
||
SHADER_OPTIMIZATION kVertexShader
|
||
--eliminate-dead-branches
|
||
--merge-return
|
||
--eliminate-dead-code-aggressive
|
||
END
|
||
ATTACH kFragmentShader ENTRY_POINT red
|
||
|
||
FRAMEBUFFER_SIZE 256 256
|
||
BIND BUFFER kImgBuffer AS color LOCATION 0
|
||
END # pipeline
|
||
|
||
PIPELINE graphics kGreenPipeline
|
||
ATTACH kVertexShader
|
||
ATTACH kFragmentShader ENTRY_POINT green
|
||
|
||
FRAMEBUFFER_SIZE 256 256
|
||
BIND BUFFER kImgBuffer AS color LOCATION 0
|
||
END # pipeline
|
||
|
||
RUN kRedPipeline DRAW_RECT POS 0 0 SIZE 256 256
|
||
RUN kGreenPipeline DRAW_RECT POS 128 128 SIZE 256 256
|
||
|
||
EXPECT kImgBuffer IDX 0 0 SIZE 127 127 EQ_RGB 255 0 0
|
||
EXPECT kImgBuffer IDX 128 128 SIZE 128 128 EQ_RGB 0 255 0
|
||
```
|
||
|
||
### Buffers
|
||
|
||
```groovy
|
||
#!amber
|
||
|
||
SHADER vertex kVertexShader GLSL
|
||
#version 430
|
||
|
||
layout(location = 0) in vec4 position;
|
||
layout(location = 1) in vec4 color_in;
|
||
layout(location = 0) out vec4 color_out;
|
||
|
||
void main() {
|
||
gl_Position = position;
|
||
color_out = color_in;
|
||
}
|
||
END # shader
|
||
|
||
SHADER fragment kFragmentShader GLSL
|
||
#version 430
|
||
|
||
layout(location = 0) in vec4 color_in;
|
||
layout(location = 0) out vec4 color_out;
|
||
|
||
void main() {
|
||
color_out = color_in;
|
||
}
|
||
END # shader
|
||
|
||
BUFFER kPosData DATA_TYPE vec2<int32> DATA
|
||
# Top-left
|
||
-1 -1
|
||
0 -1
|
||
-1 0
|
||
0 0
|
||
# Top-right
|
||
0 -1
|
||
1 -1
|
||
0 0
|
||
1 0
|
||
# Bottom-left
|
||
-1 0
|
||
0 0
|
||
-1 1
|
||
0 1
|
||
# Bottom-right
|
||
0 0
|
||
1 0
|
||
0 1
|
||
1 1
|
||
END
|
||
|
||
BUFFER kColorData DATA_TYPE uint32 DATA
|
||
# red
|
||
0xff0000ff
|
||
0xff0000ff
|
||
0xff0000ff
|
||
0xff0000ff
|
||
|
||
# green
|
||
0xff00ff00
|
||
0xff00ff00
|
||
0xff00ff00
|
||
0xff00ff00
|
||
|
||
# blue
|
||
0xffff0000
|
||
0xffff0000
|
||
0xffff0000
|
||
0xffff0000
|
||
|
||
# purple
|
||
0xff800080
|
||
0xff800080
|
||
0xff800080
|
||
0xff800080
|
||
END
|
||
|
||
BUFFER kIndices DATA_TYPE int32 DATA
|
||
0 1 2 2 1 3
|
||
4 5 6 6 5 7
|
||
8 9 10 10 9 11
|
||
12 13 14 14 13 15
|
||
END
|
||
|
||
PIPELINE graphics kGraphicsPipeline
|
||
ATTACH kVertexShader
|
||
ATTACH kFragmentShader
|
||
|
||
VERTEX_DATA kPosData LOCATION 0
|
||
VERTEX_DATA kColorData LOCATION 1
|
||
INDEX_DATA kIndices
|
||
END # pipeline
|
||
|
||
CLEAR_COLOR kGraphicsPipeline 255 0 0 255
|
||
CLEAR kGraphicsPipeline
|
||
|
||
RUN kGraphicsPipeline DRAW_ARRAY AS TRIANGLE_LIST START_IDX 0 COUNT 24
|
||
```
|
||
|
||
### OpenCL-C Shaders
|
||
|
||
```groovy
|
||
SHADER compute my_shader OPENCL-C
|
||
kernel void line(const int* in, global int* out, int m, int b) {
|
||
*out = *in * m + b;
|
||
}
|
||
END
|
||
|
||
BUFFER in_buf DATA_TYPE int32 DATA 4 END
|
||
BUFFER out_buf DATA_TYPE int32 DATA 0 END
|
||
|
||
PIPELINE compute my_pipeline
|
||
ATTACH my_shader ENTRY_POINT line
|
||
COMPILE_OPTIONS
|
||
-cluster-pod-kernel-args
|
||
-pod-ubo
|
||
-constant-args-ubo
|
||
-max-ubo-size=128
|
||
END
|
||
BIND BUFFER in_buf KERNEL ARG_NAME in
|
||
BIND BUFFER out_buf KERNEL ARG_NAME out
|
||
SET KERNEL ARG_NAME m AS int32 3
|
||
SET KERNEL ARG_NAME b AS int32 1
|
||
END
|
||
|
||
RUN my_pipeline 1 1 1
|
||
|
||
EXPECT out_buf EQ IDX 0 EQ 13
|
||
```
|
||
|
||
### Image Formats
|
||
* `A1R5G5B5_UNORM_PACK16`
|
||
* `A2B10G10R10_SINT_PACK32`
|
||
* `A2B10G10R10_SNORM_PACK32`
|
||
* `A2B10G10R10_SSCALED_PACK32`
|
||
* `A2B10G10R10_UINT_PACK32`
|
||
* `A2B10G10R10_UNORM_PACK32`
|
||
* `A2B10G10R10_USCALED_PACK32`
|
||
* `A2R10G10B10_SINT_PACK32`
|
||
* `A2R10G10B10_SNORM_PACK32`
|
||
* `A2R10G10B10_SSCALED_PACK32`
|
||
* `A2R10G10B10_UINT_PACK32`
|
||
* `A2R10G10B10_UNORM_PACK32`
|
||
* `A2R10G10B10_USCALED_PACK32`
|
||
* `A8B8G8R8_SINT_PACK32`
|
||
* `A8B8G8R8_SNORM_PACK32`
|
||
* `A8B8G8R8_SRGB_PACK32`
|
||
* `A8B8G8R8_SSCALED_PACK32`
|
||
* `A8B8G8R8_UINT_PACK32`
|
||
* `A8B8G8R8_UNORM_PACK32`
|
||
* `A8B8G8R8_USCALED_PACK32`
|
||
* `B10G11R11_UFLOAT_PACK32`
|
||
* `B4G4R4A4_UNORM_PACK16`
|
||
* `B5G5R5A1_UNORM_PACK16`
|
||
* `B5G6R5_UNORM_PACK16`
|
||
* `B8G8R8A8_SINT`
|
||
* `B8G8R8A8_SNORM`
|
||
* `B8G8R8A8_SRGB`
|
||
* `B8G8R8A8_SSCALED`
|
||
* `B8G8R8A8_UINT`
|
||
* `B8G8R8A8_UNORM`
|
||
* `B8G8R8A8_USCALED`
|
||
* `B8G8R8_SINT`
|
||
* `B8G8R8_SNORM`
|
||
* `B8G8R8_SRGB`
|
||
* `B8G8R8_SSCALED`
|
||
* `B8G8R8_UINT`
|
||
* `B8G8R8_UNORM`
|
||
* `B8G8R8_USCALED`
|
||
* `D16_UNORM`
|
||
* `D16_UNORM_S8_UINT`
|
||
* `D24_UNORM_S8_UINT`
|
||
* `D32_SFLOAT`
|
||
* `D32_SFLOAT_S8_UINT`
|
||
* `R16G16B16A16_SFLOAT`
|
||
* `R16G16B16A16_SINT`
|
||
* `R16G16B16A16_SNORM`
|
||
* `R16G16B16A16_SSCALED`
|
||
* `R16G16B16A16_UINT`
|
||
* `R16G16B16A16_UNORM`
|
||
* `R16G16B16A16_USCALED`
|
||
* `R16G16B16_SFLOAT`
|
||
* `R16G16B16_SINT`
|
||
* `R16G16B16_SNORM`
|
||
* `R16G16B16_SSCALED`
|
||
* `R16G16B16_UINT`
|
||
* `R16G16B16_UNORM`
|
||
* `R16G16B16_USCALED`
|
||
* `R16G16_SFLOAT`
|
||
* `R16G16_SINT`
|
||
* `R16G16_SNORM`
|
||
* `R16G16_SSCALED`
|
||
* `R16G16_UINT`
|
||
* `R16G16_UNORM`
|
||
* `R16G16_USCALED`
|
||
* `R16_SFLOAT`
|
||
* `R16_SINT`
|
||
* `R16_SNORM`
|
||
* `R16_SSCALED`
|
||
* `R16_UINT`
|
||
* `R16_UNORM`
|
||
* `R16_USCALED`
|
||
* `R32G32B32A32_SFLOAT`
|
||
* `R32G32B32A32_SINT`
|
||
* `R32G32B32A32_UINT`
|
||
* `R32G32B32_SFLOAT`
|
||
* `R32G32B32_SINT`
|
||
* `R32G32B32_UINT`
|
||
* `R32G32_SFLOAT`
|
||
* `R32G32_SINT`
|
||
* `R32G32_UINT`
|
||
* `R32_SFLOAT`
|
||
* `R32_SINT`
|
||
* `R32_UINT`
|
||
* `R4G4B4A4_UNORM_PACK16`
|
||
* `R4G4_UNORM_PACK8`
|
||
* `R5G5B5A1_UNORM_PACK16`
|
||
* `R5G6B5_UNORM_PACK16`
|
||
* `R64G64B64A64_SFLOAT`
|
||
* `R64G64B64A64_SINT`
|
||
* `R64G64B64A64_UINT`
|
||
* `R64G64B64_SFLOAT`
|
||
* `R64G64B64_SINT`
|
||
* `R64G64B64_UINT`
|
||
* `R64G64_SFLOAT`
|
||
* `R64G64_SINT`
|
||
* `R64G64_UINT`
|
||
* `R64_SFLOAT`
|
||
* `R64_SINT`
|
||
* `R64_UINT`
|
||
* `R8G8B8A8_SINT`
|
||
* `R8G8B8A8_SNORM`
|
||
* `R8G8B8A8_SRGB`
|
||
* `R8G8B8A8_SSCALED`
|
||
* `R8G8B8A8_UINT`
|
||
* `R8G8B8A8_UNORM`
|
||
* `R8G8B8A8_USCALED`
|
||
* `R8G8B8_SINT`
|
||
* `R8G8B8_SNORM`
|
||
* `R8G8B8_SRGB`
|
||
* `R8G8B8_SSCALED`
|
||
* `R8G8B8_UINT`
|
||
* `R8G8B8_UNORM`
|
||
* `R8G8B8_USCALED`
|
||
* `R8G8_SINT`
|
||
* `R8G8_SNORM`
|
||
* `R8G8_SRGB`
|
||
* `R8G8_SSCALED`
|
||
* `R8G8_UINT`
|
||
* `R8G8_UNORM`
|
||
* `R8G8_USCALED`
|
||
* `R8_SINT`
|
||
* `R8_SNORM`
|
||
* `R8_SRGB`
|
||
* `R8_SSCALED`
|
||
* `R8_UINT`
|
||
* `R8_UNORM`
|
||
* `R8_USCALED`
|
||
* `S8_UINT`
|
||
* `X8_D24_UNORM_PACK32`
|