KhronosGroup / OpenGL-API

OpenGL and OpenGL ES API Issue Tracker
34 stars 5 forks source link

Interactions between GL_NV_primitive_restart and OpenGL 3.1+ are undefined #75

Open ianromanick opened 3 years ago

ianromanick commented 3 years ago

In GL_NV_primitive_restart, the enable and the restart index are client state. In unextended OpenGL 3.1 or OpenGL 3.2+ Core Profile, there is, effectively, no client vertex state. As a result, the enable and the restart index are server state. In unextended OpenGL 3.1 or OpenGL 3.2+ Core Profile, it is not possible to expose the extension, so there is no problem.

In extended OpenGL 3.1 or OpenGL 3.2+ Compatibility Profile, it is possible to expose GL_NV_primitve_restart in addition to the core feature. However, the extension spec was never updated with any interactions. What happens in the following code?

    glEnable(GL_PRIMITIVE_RESTART);
    glClientEnable(GL_PRIMITIVE_RESTART_NV);
    glPrimitiveRestartIndex(1);
    glPrimitiveRestartIndexNV(2);
    glDrawElements(...);                           /* 1 */

    glDisable(GL_PRIMITIVE_RESTART);
    glDrawElements(...);                           /* 2 */

    glEnable(GL_PRIMITIVE_RESTART);
    glClientDisable(GL_PRIMITIVE_RESTART_NV);
    glDrawElements(...);                           /* 3 */

In draw 1, what is the primitive restart index? In draws 2 and 3, is primitive restart enabled or not?

Thinking about how this could work with GLX protocol, my guess would be that when both GL_PRIMITVE_RESTART and GL_PRIMITVE_RESTART_NV are enabled, the state for GL_PRIMITVE_RESTART_NV is used. If only of GL_PRIMITVE_RESTART or GL_PRIMITVE_RESTART_NV is enabled, the enabled state is used.

ianromanick commented 3 years ago

It's also worth noting that the spec is a little unclear as to whether or not GL_PRIMITIVE_RESTART_NV state affects glPrimitiveRestartNV. It strongly implies that it is not affected. GL_PRIMITIVE_RESTART_NV is client state, but GLX protocol is (partially) defined for glPrimitiveRestartNV. The idea is that when the GLX client library decomposes glDrawElements into immediate mode drawing commands, it will emit glPrimitiveRestartNV (instead of glVertex, etc.) when the restart index is encountered.

If this issue results in an update to the GL_NV_primitive_restart spec, it would be nice to add something like the following to section 2.6.X Primitive Restarts:

The operation of PrimitiveRestartNV is not affected by the setting of PRIMITIVE_RESTART_NV.

pdaniell-nv commented 3 years ago

The NVIDIA implementation of GL_NV_primitive_restart is totally equivalent to the core functionality:

  1. glPrimitiveRestartIndexNV == glPrimitiveRestartIndex
  2. GL_PRIMITIVE_RESTART_NV == GL_PRIMITIVE_RESTART
  3. glClientEnable(GL_PRIMITIVE_RESTART_NV) == glEnable(GL_PRIMITIVE_RESTART)
  4. glPrimitiveRestartNV == glPrimitiveRestart
ianromanick commented 3 years ago

So.... do both glPushAttrib and glPushClientAttrib save primitive restart index and enable? And both glPopAttrib and glPopClientAttrib restore? From independent stacks?

Is there any chance of getting the extension spec update to document these (quite surprising) interactions?

pdaniell-nv commented 3 years ago

Only gl{Push,Pop}ClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT) saves/restores it.