Variable-length SSBOs

Problems building or running the engine, queries about how to use features etc.
Adrian Samoticha
Gnoblar
Posts: 6
Joined: Sun Mar 23, 2025 8:50 pm

Variable-length SSBOs

Post by Adrian Samoticha »

Ogre Version: 14-3-4
Operating System: Windows 11
Render System: GL3+

Hey! :D

I have a GLSL fragment shader that uses a Shared Shader Buffer Object to store voxel data that looks like this:

Code: Select all

layout (std430, binding = 0) buffer VoxelData
{
    uint voxelData[262144];
};

The voxel data is supplied to the shader as follows:

Code: Select all

constexpr auto bufferSize = 262144;
voxelData.resize(bufferSize);
for (int i = 0; i < bufferSize; i++) {
  voxelData[i] = i;
}
const auto sharedParams =
    Ogre::GpuProgramManager::getSingleton().getSharedParameters("VoxelData");
sharedParams->setNamedConstant("voxelData", voxelData.data(), bufferSize);

However, I need a dynamically-sized buffer whose length I can choose arbitrarily during runtime. As far as Iʼm aware, GLSL supports that using the following syntax, as long as the variable-length array is the last member of the buffer:

Code: Select all

layout (std430, binding = 0) buffer VoxelData
{
    uint voxelData[];
};

However, the SSBO needs to be defined as a shared parameter in the material script, which I currently do like this:

Code: Select all

shared_params VoxelData
{
    shared_param_named voxelData uint [262144]
}

I simply cannot figure out how to define a variable-size shared parameter in the material script. I tried using [], but that didnʼt work. The documentation doesnʼt seem to cover that, either.

I have also considered using Hardware Buffers instead. Curiously though, the Ogre::HardwareBufferManager class doesnʼt seem to provide a method for creating “plain” SSBO-related buffers, only vertex, uniform, or index buffers. I suspect that what I actually need is an Ogre::GL3PlusHardwareBuffer, but there does not seem to be a way to obtain one through the hardware buffer manager. The documentation also isnʼt very clear about how to read the data back from the fragment shader once youʼve created the buffer on the CPU side.

At this point, I am honestly not sure if Iʼm on the right track anymore, so any help is greatly appreciated! :)

paroj
OGRE Team Member
OGRE Team Member
Posts: 2151
Joined: Sun Mar 30, 2014 2:51 pm
x 1156

Re: Variable-length SSBOs

Post by paroj »

The variable size in the shader merely allows you to bind SSBOs of different size to the same shader. The SSBOs themselves must have a fixed size on the CPU/ GPU.
I suggest declaring the maximum needed size in the material script and pushing the actually used size via an uniform. This will be also the fastest approach as re-creating buffers is costly. If anything goes wrong with this, it is a bug with Ogre.

That said SSBOs are not much used so far and we try to expose only a minimal API which might be incomplete:

  • there is no convenience methods to resize Ogre buffers; you have to create a new buffer and manually copy the contents
  • there is no API to manually create SSBOs. They are created internally by the RenderSystem after parsing the shader
Adrian Samoticha
Gnoblar
Posts: 6
Joined: Sun Mar 23, 2025 8:50 pm

Re: Variable-length SSBOs

Post by Adrian Samoticha »

paroj wrote: Sun Apr 13, 2025 2:03 pm

The variable size in the shader merely allows you to bind SSBOs of different size to the same shader. The SSBOs themselves must have a fixed size on the CPU/ GPU.
I suggest declaring the maximum needed size in the material script and pushing the actually used size via an uniform. This will be also the fastest approach as re-creating buffers is costly. If anything goes wrong with this, it is a bug with Ogre.

That said SSBOs are not much used so far and we try to expose only a minimal API which might be incomplete:

  • there is no convenience methods to resize Ogre buffers; you have to create a new buffer and manually copy the contents
  • there is no API to manually create SSBOs. They are created internally by the RenderSystem after parsing the shader

Iʼm completely fine with needing to re-create my SSBOs and copy over the contents to get a buffer with a different size. Iʼm also fine with that being a slow operation since itʼs going to be performed rarely.
Iʼm not sure if there is such a thing as a “maximum needed size” in my application, though. Ideally, Iʼd want my buffer to work somewhat like std::vector. Its memory usage is typically higher than the amount of actual data it holds to reduce the number of reallocations, but it doesnʼt impose any strict limit on its size, and it doesnʼt consume the amount of memory equal to some theoretical maximum size.
Being able to create arbitrarily-sized SSBOs during runtime would allow me to implement something like this.

paroj
OGRE Team Member
OGRE Team Member
Posts: 2151
Joined: Sun Mar 30, 2014 2:51 pm
x 1156

Re: Variable-length SSBOs

Post by paroj »

I would say that the maximal dimensions of your voxel world gives you the maximal number of voxels which determines the buffer size.

However, feel free to patch Ogre the way it seems fit to you and propose a PR so we can discuss the API you need in more detail.