Based on my knowledge, this is unfortunately a known limitation of Godot's rendering architecture, not something specific to the Spine runtime implementation.
Why This Happens:
Godot currently does not implement batching for 2D triangle meshes. Each SpineMesh2D node results in a separate draw call, which is why you're seeing the 1:1 correlation between slots and draw calls.
The Spine team has worked around this limitation as best as possible by using meshes explicitly in the implementation (EsotericSoftware/spine-runtimesblob/4.2/spine-godot/spine_godot/SpineSprite.cpp#L173), which does improve performance compared to canvas_item_add_triangle_array, but it cannot solve the batching issue.
Important Context:
However, there's good news: Godot 4+ uses Vulkan (or other modern renderers like Forward+) as the default renderer. With modern rendering APIs, batching is much less impactful on performance than it was with older OpenGL-based renderers. This is one of the reasons the Godot team hasn't prioritized implementing 2D mesh batching yet.
You can track the status of this feature request here:
orgs/godotengineprojects/33?pane=issue&itemId=20224421
What You Can Do:
Since you mentioned optimizing for older hardware:
- Reduce slot count - Combine attachments where possible in the Spine Editor to minimize the number of active slots
- Use simpler skeletons - Consider creating lower-detail versions of characters for older hardware
- Profile carefully - The draw call count may look high, but the actual performance impact on Vulkan/Forward+ renderers is much lower than you might expect from OpenGL experience
The SubViewport placement shouldn't be causing additional issues beyond the base limitation - the batching failure exists at the fundamental Godot 2D mesh rendering level.