QShaderDescription Class

Describes the interface of a shader. More...

Header: #include <QShaderDescription>
qmake: QT += rhi
Since: Qt 5.14

Public Types

class BlockVariable
class InOutVariable
class PushConstantBlock
class StorageBlock
class UniformBlock
enum ImageFlag { ReadOnlyImage, WriteOnlyImage }
flags ImageFlags
enum ImageFormat { ImageFormatUnknown, ImageFormatRgba32f, ImageFormatRgba16f, ImageFormatR32f, ..., ImageFormatR8ui }
enum VariableType { Unknown, Float, Vec2, Vec3, ..., Struct }

Public Functions

QShaderDescription()
~QShaderDescription()
QVector<QShaderDescription::InOutVariable> combinedImageSamplers() const
QVector<QShaderDescription::InOutVariable> inputVariables() const
bool isValid() const
QVector<QShaderDescription::InOutVariable> outputVariables() const
QVector<QShaderDescription::PushConstantBlock> pushConstantBlocks() const
QVector<QShaderDescription::StorageBlock> storageBlocks() const
QVector<QShaderDescription::InOutVariable> storageImages() const
QByteArray toBinaryJson() const
QByteArray toJson() const
QVector<QShaderDescription::UniformBlock> uniformBlocks() const

Static Public Members

QShaderDescription fromBinaryJson(const QByteArray &data)

Detailed Description

Describes the interface of a shader.

A shader typically has a set of inputs and outputs. A vertex shader for example has a number of input variables and may use one or more uniform buffers to access data (e.g. a modelview matrix) provided by the application. The shader for the fragment stage receives data from the vertex stage (in a simple setup) and may also rely on data from uniform buffers, images, and samplers.

When it comes to vertex inputs and the layout of the uniform buffers (what are the names of the members? what is there size, offset, and so on), applications and frameworks may need to discover this dynamically at run time. This is typical when the shader is not built-in but provided by an external entity, like the user.

Modern and lean graphics APIs may no longer provide a way to query shader reflection information at run time. Therefore, such data is now automatically generated by QShaderBaker and is provided as a QShaderDescription object for each and every QShader.

Example

Take the following vertex shader:


  #version 440

  layout(location = 0) in vec4 position;
  layout(location = 1) in vec3 color;
  layout(location = 0) out vec3 v_color;

  layout(std140, binding = 0) uniform buf {
      mat4 mvp;
      float opacity;
  } ubuf;

  out gl_PerVertex { vec4 gl_Position; };

  void main()
  {
      v_color = color;
      gl_Position = ubuf.mvp * position;
  }

This shader has two inputs: position at location 0 with a type of vec4, and color at location 1 with a type of vec3. It has one output: v_color, although this is typically not interesting for applications. What is more important, there is a uniform block at binding 0 with a size of 68 bytes and two members, a 4x4 matrix named mvp at offset 0, and a float opacity at offset 64.

All this is described by a QShaderDescription object. QShaderDescription can also be serialized to JSON and binary JSON, and can be deserialized from binary JSON. In practice this is rarely needed since QShader takes care of the associated QShaderDescription automatically, but if the QShaderDescription of the above shader would be written out as JSON, it would look like the following:


  {
      "inputs": [
          {
              "location": 1,
              "name": "color",
              "type": "vec3"
          },
          {
              "location": 0,
              "name": "position",
              "type": "vec4"
          }
      ],
      "outputs": [
          {
              "location": 0,
              "name": "v_color",
              "type": "vec3"
          }
      ],
      "uniformBlocks": [
          {
              "binding": 0,
              "blockName": "buf",
              "members": [
                  {
                      "matrixStride": 16,
                      "name": "mvp",
                      "offset": 0,
                      "size": 64,
                      "type": "mat4"
                  },
                  {
                      "name": "opacity",
                      "offset": 64,
                      "size": 4,
                      "type": "float"
                  }
              ],
              "set": 0,
              "size": 68,
              "structName": "ubuf"
          }
      ]
  }

The C++ API allows accessing a data structure like the above. For simplicity the inner structs only contain public data members, also considering that their layout is unlikely to change in the future.

See also QShaderBaker and QShader.

Member Type Documentation

enum QShaderDescription::ImageFlag
flags QShaderDescription::ImageFlags

The ImageFlags type is a typedef for QFlags<ImageFlag>. It stores an OR combination of ImageFlag values.

enum QShaderDescription::ImageFormat

enum QShaderDescription::VariableType

Represents the type of a variable or block member.

ConstantValue
QShaderDescription::Unknown0
QShaderDescription::Float1
QShaderDescription::Vec22
QShaderDescription::Vec33
QShaderDescription::Vec44
QShaderDescription::Mat25
QShaderDescription::Mat2x36
QShaderDescription::Mat2x47
QShaderDescription::Mat38
QShaderDescription::Mat3x29
QShaderDescription::Mat3x410
QShaderDescription::Mat411
QShaderDescription::Mat4x212
QShaderDescription::Mat4x313
QShaderDescription::Int14
QShaderDescription::Int215
QShaderDescription::Int316
QShaderDescription::Int417
QShaderDescription::Uint18
QShaderDescription::Uint219
QShaderDescription::Uint320
QShaderDescription::Uint421
QShaderDescription::Bool22
QShaderDescription::Bool223
QShaderDescription::Bool324
QShaderDescription::Bool425
QShaderDescription::Double26
QShaderDescription::Double227
QShaderDescription::Double328
QShaderDescription::Double429
QShaderDescription::DMat230
QShaderDescription::DMat2x331
QShaderDescription::DMat2x432
QShaderDescription::DMat333
QShaderDescription::DMat3x234
QShaderDescription::DMat3x435
QShaderDescription::DMat436
QShaderDescription::DMat4x237
QShaderDescription::DMat4x338
QShaderDescription::Sampler1D39
QShaderDescription::Sampler2D40
QShaderDescription::Sampler2DMS41
QShaderDescription::Sampler3D42
QShaderDescription::SamplerCube43
QShaderDescription::Sampler1DArray44
QShaderDescription::Sampler2DArray45
QShaderDescription::Sampler2DMSArray46
QShaderDescription::Sampler3DArray47
QShaderDescription::SamplerCubeArray48
QShaderDescription::SamplerRect49
QShaderDescription::SamplerBuffer50
QShaderDescription::Image1D51
QShaderDescription::Image2D52
QShaderDescription::Image2DMS53
QShaderDescription::Image3D54
QShaderDescription::ImageCube55
QShaderDescription::Image1DArray56
QShaderDescription::Image2DArray57
QShaderDescription::Image2DMSArray58
QShaderDescription::Image3DArray59
QShaderDescription::ImageCubeArray60
QShaderDescription::ImageRect61
QShaderDescription::ImageBuffer62
QShaderDescription::Struct63

Property Documentation

Member Function Documentation

QShaderDescription::QShaderDescription()

Constructs a new, empty QShaderDescription.

Note: Being empty implies that isValid() returns false for the newly constructed instance.

QShaderDescription::~QShaderDescription()

Destructor.

QVector<QShaderDescription::InOutVariable> QShaderDescription::combinedImageSamplers() const

Returns the list of combined image samplers

With GLSL/Vulkan shaders as source a layout(binding = 1) uniform sampler2D tex; uniform generates the following: (shown as textual JSON here)


  "combinedImageSamplers": [
       {
           "binding": 1,
           "name": "tex",
           "set": 0,
           "type": "sampler2D"
       }
   ]

This does not mean that other language versions of the shader must also use a combined image sampler, especially considering that the concept may not exist everywhere. For instance, a HLSL version will likely just use a Texture2D and SamplerState object with registers t1 and s1, respectively.

[static] QShaderDescription QShaderDescription::fromBinaryJson(const QByteArray &data)

Deserializes the given binary JSON data and returns a new QShaderDescription.

QVector<QShaderDescription::InOutVariable> QShaderDescription::inputVariables() const

Returns the list of input variables. This includes vertex inputs (sometimes called attributes) for the vertex stage, and inputs for other stages (sometimes called varyings).

bool QShaderDescription::isValid() const

Returns true if the QShaderDescription contains at least one entry in one of the variable and block lists.

QVector<QShaderDescription::InOutVariable> QShaderDescription::outputVariables() const

Returns the list of output variables.

QVector<QShaderDescription::PushConstantBlock> QShaderDescription::pushConstantBlocks() const

Returns the list of push constant blocks.

Note: Avoid relying on push constant blocks for shaders that are to be used in combination with the Qt Rendering Hardware Interface since that currently has no support for them.

QVector<QShaderDescription::StorageBlock> QShaderDescription::storageBlocks() const

Returns the list of shader storage blocks.

For example, with GLSL/Vulkan shaders as source, the declaration


  struct Stuff {
      vec2 a;
      vec2 b;
  };
  layout(std140, binding = 0) buffer StuffSsbo {
      vec4 whatever;
      Stuff stuff[];
  } buf;

generates the following: (shown as textual JSON here)


  "storageBlocks": [ {
      "binding": 0,
      "blockName": "StuffSsbo",
      "instanceName": "buf",
      "knownSize": 16,
      "members": [
          {
              "name": "whatever",
              "offset": 0,
              "size": 16,
              "type": "vec4"
          },
          {
              "arrayDims": [
                  0
              ],
              "name": "stuff",
              "offset": 16,
              "size": 0,
              "structMembers": [
                  {
                      "name": "a",
                      "offset": 0,
                      "size": 8,
                      "type": "vec2"
                  },
                  {
                      "name": "b",
                      "offset": 8,
                      "size": 8,
                      "type": "vec2"
                  }
              ],
              "type": "struct"
          }
      ],
      "set": 0
  } ]

Note: The size of the last member in the storage block is undefined. This shows up as size 0 and an array dimension of [0]. The storage block's knownSize excludes the size of the last member since that will only be known at run time.

Note: SSBOs are not available with some graphics APIs, such as, OpenGL 2.x or OpenGL ES older than 3.1.

QVector<QShaderDescription::InOutVariable> QShaderDescription::storageImages() const

Returns the list of image variables.

These will likely occur in compute shaders. For example, layout (binding = 0, rgba8) uniform readonly image2D inputImage; generates the following: (shown as textual JSON here)


  "storageImages": [
       {
           "binding": 0,
           "imageFormat": "rgba8",
           "name": "inputImage",
           "set": 0,
           "type": "image2D"
       }
   ]

Note: Separate image objects are not compatible with some graphics APIs, such as, OpenGL 2.x or OpenGL ES older than 3.1.

QByteArray QShaderDescription::toBinaryJson() const

Returns a serialized binary version of the data.

See also toJson().

QByteArray QShaderDescription::toJson() const

Returns a serialized JSON text version of the data.

Note: There is no deserialization method provided for JSON text.

See also toBinaryJson().

QVector<QShaderDescription::UniformBlock> QShaderDescription::uniformBlocks() const

Returns the list of uniform blocks.

Member Variable Documentation

Related Non-Members

Macro Documentation