|
|
# 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`
|
|
|
|
|
|
|
|
|
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}
|
|
|
```
|
|
|
|
|
|
#### 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
|
|
|
```
|
|
|
|
|
|
```groovy
|
|
|
# Set the size of the render buffers. |width| and |height| are integers and
|
|
|
# default to 250x250.
|
|
|
FRAMEBUFFER_SIZE _width_ _height_
|
|
|
```
|
|
|
|
|
|
```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
|
|
|
SUBROUP {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 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 offsets should be provided via `OFFSET offset1 offset2 ...`
|
|
|
when using dynamic buffers with BUFFER_ARRAY.
|
|
|
```groovy
|
|
|
# Bind the buffer of the given |buffer_type| at the given descriptor set
|
|
|
# and binding. The buffer will use a start index of 0.
|
|
|
BIND {BUFFER | BUFFER_ARRAY} {buffer_name} AS {buffer_type} DESCRIPTOR_SET _id_ \
|
|
|
BINDING _id_
|
|
|
|
|
|
# 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 start index of |offset|.
|
|
|
BIND {BUFFER | BUFFER_ARRAY} {buffer_name} AS {uniform_dynamic | storage_dynamic} \
|
|
|
DESCRIPTOR_SET _id_ BINDING _id_ OFFSET _offset_
|
|
|
```
|
|
|
|
|
|
```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`
|