The InitInfo struct is a member of the GameInstance, and it handles information about how the engine should behave. Currently, it has the following fields:

  1. ShaderConstantStruct shaderConstantStruct
  2. ShaderMutableStruct shaderMutableStruct
  3. ShaderPushConstant shaderPushConstant

Shader structs

Theory

The ShaderConstantStruct is a struct that contains constant variables for the shaders, which are deployed using a uniform buffer(Go to the developer section to learn more!). We say constants but to clarify they are values that are the same across all objects using the shader, which means that you can change the values, but those values will change to be the same for all objects.

The ShaderPushConstant struct defines a push constant(Got to the developer section to learn more). Push constants are small packets of data, with a maximum size of 128 bits(16 bytes) that can be sent to the given shader with low overhead. Unlike the ShaderConstantStruct, they are unique per object.

The ShaderMutableStruct struct defines a dynamic uniform buffer(Go to the developer section to learn more). They're like push constants in the way that their data is unique per object. The differences are that they are higher overhead and are not limited in size.

Creating the structs

To create the structs, declare new structs to derive from the base ones in the header of your GameInstance, like this:

struct ShaderConstants : public ShaderConstantBase
{

} shaderConstantStruct;

struct ShaderPushConst : public ShaderPushConstantBase
{

} shaderPushConst;

struct Mutable
{

} mutableS;

Next, add your custom variables, then in the init function of the game instance add the following lines:

initInfo.shaderConstantStruct = 
{
    .data = &shaderConstantStruct,
    .size = sizeof(shaderConstantStruct)
};
initInfo.shaderMutableStruct =
{
    .data = (void*)&mutableS,
    .size = sizeof(mutableS)
};
initInfo.shaderPushConstant =
{
    .data = &shaderPushConst,
    .size = sizeof(shaderPushConst)
};

and change your shader code accordingly

Developer

The shader structs are an abstraction on top of the basic Vulkan shader layout. The ShaderConstantStruct being a Uniform Buffer is required because we have a very limited number of Uniform Buffers available on the GPU, so we cannot make one that's unique to every object. So we just create a single Uniform Buffer to hold all constants.

On the other hand, the PushConstantStruct is there because we have 64 bits left over after the default mesh model matrix is set, so a bit of data can still be pushed.

The ShaderMutableStruct being a Dynamic Uniform Buffer means that all data is stored in a large buffer containing the uniform data for every object with a specific alignment. Since it doesn't have the limits of the PushConstantStruct, it's preferred for large objects.