Name NV_timeline_semaphore Name Strings GL_NV_timeline_semaphore Contributors Carsten Rohde, NVIDIA James Jones, NVIDIA Contact Carsten Rohde, NVIDIA Corporation (crohde 'at' nvidia.com) Status Complete Version Last Modified Date: Jul 10, 2020 Revision: 1 Number 551 OpenGL ES Extension #330 Dependencies Written against the OpenGL 4.6 and OpenGL ES 3.2 specifications. GL_NV_timeline_semaphore requires GL_EXT_semaphore or a version of OpenGL or OpenGL ES that incorporates it. Overview The Vulkan API introduces the concept of timeline semaphores. This extension brings those concepts to the OpenGL API by adding a semaphore type to the semaphore object. In OpenGL, timeline semaphore signal and wait operations are similar to the corresponding operations on imported Direct3D 12 fences defined in EXT_external_objects_win32. New Procedures and Functions void CreateSemaphoresNV(sizei n, uint *semaphores); void SemaphoreParameterivNV(uint semaphore, enum pname, const GLint *params); void GetSemaphoreParameterivNV(uint semaphore, enum pname, int *params); New Tokens Accepted by the parameter of SemaphoreParameterivNV and GetSemaphoreParameterivNV: SEMAPHORE_TYPE_NV 0x95B3 Accepted by the parameter of SemaphoreParameterivNV and GetSemaphoreParameterivNV when parameter is SEMAPHORE_TYPE_NV: SEMAPHORE_TYPE_BINARY_NV 0x95B4 SEMAPHORE_TYPE_TIMELINE_NV 0x95B5 Accepted by the parameter of SemaphoreParameterui64vNV and GetSemaphoreParameterui64vNV: TIMELINE_SEMAPHORE_VALUE_NV 0x9595 Accepted by the parameter to GetIntegerv, GetFloatv, GetDoublev, GetInteger64v, and GetBooleanv: MAX_TIMELINE_SEMAPHORE_VALUE_DIFFERENCE_NV 0x95B6 Additions to Chapter 4 of the OpenGL 4.6 Specification (Event Model) Add the following to section 4.2 Semaphore Objects after paragraph which describes command GenSemaphoresEXT: The command void CreateSemaphoresNV(sizei n, uint *semaphores); returns previously unused semaphore names in . The semaphores named contain default state, but initially have no external semaphores associated with them. Replace section 4.2.2 Semaphore Parameters with the following: Semaphore parameters control the type of the semaphore and how semaphore wait and signal operations behave. Table 4.3 defines which parameters are available for a semaphore based on the external handle type from which it was imported. Semaphore parameters are set using the commands void SemaphoreParameterivNV(uint semaphore, enum pname, const int *params); and void SemaphoreParameterui64vEXT(uint semaphore, enum pname, const uint64 *params); is the name of the semaphore object on which the parameter will be set to the value(s) in . Table 4.3: Semaphore parameters | Name | Handle Types | Legal Values | +-----------------------------+-----------------------------+--------------------------------------+ | SEMAPHORE_TYPE_NV | any handle type | SEMAPHORE_TYPE_BINARY_NV (default) | | | | SEMAPHORE_TYPE_TIMELINE_NV | +-----------------------------+-----------------------------+--------------------------------------+ | TIMELINE_SEMAPHORE_VALUE_NV | any handle type | any value | +-----------------------------+-----------------------------+--------------------------------------+ The default type of a semaphore is SEMAPHORE_TYPE_BINARY_NV. Only when the semaphore is imported from a D3D fence, the semaphore type defaults to SEMAPHORE_TYPE_TIMELINE_NV. Parameters of a semaphore object may be queried with the commands void GetSemaphoreParameteriEXT(uint semaphore, enum pname, uint64 *params); and void GetSemaphoreParameterui64EXT(uint semaphore, enum pname, uint64 *params); is the semaphore object from with the parameter is queried. The value(s) of the parameter are returned in . may be any value in table 4.3. Add the following after the first paragraph of section 4.2.3 "Waiting for Semaphores" If is of the type SEMAPHORE_TYPE_TIMELINE_NV, it will reach the signaled state when its value is greater than or equal to the value specified by its TIMELINE_SEMAPHORE_VALUE_NV parameter. Add the following at the end of section 4.2.3 "Waiting for Semaphores": When using binary semaphores, for every wait on a semaphore there must be a prior signal of that semaphore that will not be consumed by a different wait on the semaphore. When using timeline semaphores, wait-before-signal behavior is well-defined and applications can wait for semaphore before the corresponding semaphore signal operation is flushed. MAX_TIMELINE_SEMAPHORE_VALUE_DIFFERENCE_NV indicates the maximum difference allowed by the implementation between the current value of a timeline semaphore and any pending wait operations Add the following after the first paragraph of section 4.2.4 "Signaling Semaphores" If is of the type SEMAPHORE_TYPE_TIMELINE_NV, its value will be set to the value specified by its TIMELINE_SEMAPHORE_VALUE_NV parameter when the signal operation completes. Add the following at the end of section 4.2.4 "Signaling for Semaphores": MAX_TIMELINE_SEMAPHORE_VALUE_DIFFERENCE_NV indicates the maximum difference allowed by the implementation between the current value of a timeline semaphore and any pending signal operations. Example GLuint semapohre; glCreateSemaphoresNV(1, &semaphore); GLenum semaphoreType = GL_SEMAPHORE_TYPE_TIMELINE_NV; glSemaphoreParameterivNV(semaphore, GL_SEMAPHORE_TYPE_NV, (GLint*)&semaphoreType); glImportSemaphoreFdEXT(semaphore, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd); // or win32 equivalent GLuint64 semaphoreValue = 0; while (...) { glSemaphoreParameterui64vEXT(semaphore, GL_TIMELINE_SEMAPHORE_VALUE_NV, &semaphoreValue); glWaitSemaphoreEXT(semaphore, ...); ... semaphoreValue ++; glSemaphoreParameterui64vEXT(semaphore, GL_TIMELINE_SEMAPHORE_VALUE_NV, &semaphoreValue); glSignalSemaphoreEXT(semaphore, ...); } glDeleteSemaphoresEXT(1, &semaphore); Issues (1) Should we add client functions to signal and wait for the semaphore on the CPU? RESOLVED: No. We already declined to add external Vulkan fence interop with GL on the basis that you can just do that with Vulkan if you need it. (2) Should GetIntegerv and GetBooleanv be allowed to query MAX_TIMELINE_SEMAPHORE_VALUE_DIFFERENCE_NV? RESOLVED: Yes. Although it's dangerous to use them they don't throw an error but you are advised to use GetInteger64v. Revision History Revision 1, 2020-07-10 (Carsten Rohde) - Initial draft.