If you're going to have the variables inside the enums for speed, I'd use ServiceLoader to lookup the required implementation at runtime and request the underlying values from it, rather than have the implementation have to configure the enums itself - that's ... yuck!
What is a ServiceLoader? How would that work with my enums? What kind of advantages are there here?
From my point of view, an abstraction layer shouldn't contain backend-specific data in the first place.
The abstract model should have its own, backend-independent way to differentiate between
geometry types (POINTS, LINES, TRIANGLES, QUADS, SPLINES, SPHERES, something completely different) and the backends
have to map it to their own model at some point.
I agree with this, which is why I want to go with enums for the abstraction to get compile time checking of arguments. My initial idea had the OpenGL and Vulkan constants in the enum, which was bad as it meant having backend specific data in the abstraction. However, I think putting an int field in the enum that the backend can use for mapping the enum to a constant isn't the same thing and shouldn't be bad design as it has the best performance and arguable the lowest complexity and maintenance requirements.
The mapping actually has to occur just once, for example when the geometry is read from a file.
Not in my abstraction. It's just a thin layer over OpenGL and Vulkan, so data in a buffer for example isn't tied to a specific geometry topology like triangles or points. The mapping has to be done every time you submit a draw call, and there are a lot of other cases where I'll be needing to map lots of enums to int constants for OGL and VK.