Skip to content

Commit d706616

Browse files
zzueggclaude
andcommitted
fix(renderer): track UBO and SSBO binding namespaces separately
UBOs and SSBOs use separate GL binding namespaces (GL_UNIFORM_BUFFER vs GL_SHADER_STORAGE_BUFFER), so a UBO at binding 0 does not collide with an SSBO at binding 0. Track them independently in the collision detection pass to avoid unnecessary reassignments. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 775d769 commit d706616

1 file changed

Lines changed: 21 additions & 8 deletions

File tree

jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,28 +1538,41 @@ private void resolveBufferBlockBindings(final Shader shader) {
15381538
block.setBinding(binding);
15391539
}
15401540

1541-
// Pass 2: detect and resolve collisions
1542-
Set<Integer> usedBindings = new HashSet<>();
1543-
int nextFree = 0;
1541+
// Pass 2: detect and resolve collisions.
1542+
// UBOs and SSBOs use separate GL binding namespaces, so track them independently.
1543+
Set<Integer> usedUboBindings = new HashSet<>();
1544+
Set<Integer> usedSsboBindings = new HashSet<>();
1545+
int nextFreeUbo = 0;
1546+
int nextFreeSsbo = 0;
15441547

15451548
for (int i = 0; i < bufferBlocks.size(); i++) {
15461549
ShaderBufferBlock block = bufferBlocks.getValue(i);
15471550
int binding = block.getBinding();
15481551
if (binding < 0) continue;
15491552

1553+
BufferType bufferType = block.getType();
1554+
Set<Integer> usedBindings;
1555+
if (bufferType == BufferType.ShaderStorageBufferObject) {
1556+
usedBindings = usedSsboBindings;
1557+
} else {
1558+
usedBindings = usedUboBindings;
1559+
}
1560+
15501561
if (!usedBindings.add(binding)) {
1551-
// Collision — find a free binding point
1552-
while (usedBindings.contains(nextFree)) {
1553-
nextFree++;
1562+
// Collision within the same namespace — find a free binding point
1563+
if (bufferType == BufferType.ShaderStorageBufferObject) {
1564+
while (usedBindings.contains(nextFreeSsbo)) nextFreeSsbo++;
1565+
binding = nextFreeSsbo;
1566+
} else {
1567+
while (usedBindings.contains(nextFreeUbo)) nextFreeUbo++;
1568+
binding = nextFreeUbo;
15541569
}
1555-
binding = nextFree;
15561570
usedBindings.add(binding);
15571571
block.setBinding(binding);
15581572
}
15591573

15601574
// Set the binding on the shader program
15611575
int blockIndex = block.getLocation();
1562-
BufferType bufferType = block.getType();
15631576
if (bufferType == BufferType.ShaderStorageBufferObject) {
15641577
gl4.glShaderStorageBlockBinding(shaderId, blockIndex, binding);
15651578
} else {

0 commit comments

Comments
 (0)