Adding NV_timeline_semaphore
diff --git a/extensions/NV/NV_timeline_semaphore.txt b/extensions/NV/NV_timeline_semaphore.txt
new file mode 100755
index 0000000..3479fa3
--- /dev/null
+++ b/extensions/NV/NV_timeline_semaphore.txt
@@ -0,0 +1,223 @@
+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 <pname> parameter of SemaphoreParameterivNV
+    and GetSemaphoreParameterivNV:
+
+        SEMAPHORE_TYPE_NV                           0x95B3
+
+    Accepted by the <param> parameter of SemaphoreParameterivNV and
+    GetSemaphoreParameterivNV when <pname> parameter is SEMAPHORE_TYPE_NV:
+
+        SEMAPHORE_TYPE_BINARY_NV                    0x95B4
+        SEMAPHORE_TYPE_TIMELINE_NV                  0x95B5
+
+    Accepted by the <pname> parameter of SemaphoreParameterui64vNV
+    and GetSemaphoreParameterui64vNV:
+
+        TIMELINE_SEMAPHORE_VALUE_NV                 0x9595
+
+    Accepted by the <pname> 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 <n> previously unused semaphore names in <semaphores>.
+        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);
+
+        <semaphore> is the name of the semaphore object on which the
+        parameter <pname> will be set to the value(s) in <pname>.
+
+        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);
+
+        <semaphore> is the semaphore object from with the parameter <pname>
+        is queried.  The value(s) of the parameter are returned in <params>.
+        <pname> may be any value in table 4.3.
+
+    Add the following after the first paragraph of section 4.2.3 "Waiting
+    for Semaphores"
+
+        If <semaphore> 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 <semaphore> 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.
diff --git a/extensions/esext.php b/extensions/esext.php
index 35de028..9625b28 100644
--- a/extensions/esext.php
+++ b/extensions/esext.php
@@ -683,4 +683,6 @@
 </li>
 <li value=328><a href="extensions/MESA/MESA_framebuffer_swap_xy.txt">GL_MESA_framebuffer_swap_xy</a>
 </li>
+<li value=330><a href="extensions/NV/GL_NV_timeline_semaphore.txt">GL_NV_timeline_semaphore</a>
+</li>
 </ol>
diff --git a/extensions/glext.php b/extensions/glext.php
index 321dda8..d8533d7 100644
--- a/extensions/glext.php
+++ b/extensions/glext.php
@@ -1037,4 +1037,6 @@
 </li>
 <li value=549><a href="extensions/MESA/MESA_framebuffer_swap_xy.txt">GL_MESA_framebuffer_swap_xy</a>
 </li>
+<li value=551><a href="extensions/NV/GL_NV_timeline_semaphore.txt">GL_NV_timeline_semaphore</a>
+</li>
 </ol>
diff --git a/extensions/registry.py b/extensions/registry.py
index c0bea5c..977ba90 100644
--- a/extensions/registry.py
+++ b/extensions/registry.py
@@ -3937,6 +3937,13 @@
         'supporters' : { 'NVIDIA' },
         'url' : 'extensions/NV/NV_transform_feedback2.txt',
     },
+    'GL_NV_timeline_semaphore' : {
+        'number' : 551,
+        'esnumber' : 330,
+        'flags' : { 'public' },
+        'supporters' : { 'NVIDIA' },
+        'url' : 'extensions/NV/NV_timeline_semaphore.txt',
+    },
     'GL_NV_uniform_buffer_unified_memory' : {
         'number' : 459,
         'flags' : { 'public' },
diff --git a/xml/gl.xml b/xml/gl.xml
index 6a01874..ce01480 100644
--- a/xml/gl.xml
+++ b/xml/gl.xml
@@ -11571,6 +11571,7 @@
         <enum value="0x9593" name="GL_LAYOUT_TRANSFER_DST_EXT" group="TextureLayout"/>
         <enum value="0x9594" name="GL_HANDLE_TYPE_D3D12_FENCE_EXT" group="ExternalHandleType"/>
         <enum value="0x9595" name="GL_D3D12_FENCE_VALUE_EXT" group="SemaphoreParameterName"/>
+        <enum value="0x9595" name="GL_TIMELINE_SEMAPHORE_VALUE_NV" group="SemaphoreParameterName"/>
         <enum value="0x9596" name="GL_NUM_DEVICE_UUIDS_EXT" group="GetPName"/>
         <enum value="0x9597" name="GL_DEVICE_UUID_EXT" group="GetPName"/>
         <enum value="0x9598" name="GL_DRIVER_UUID_EXT" group="GetPName"/>
@@ -11598,7 +11599,12 @@
         <enum value="0x95AE" name="GL_SHADING_RATE_SAMPLE_ORDER_DEFAULT_NV"/>
         <enum value="0x95AF" name="GL_SHADING_RATE_SAMPLE_ORDER_PIXEL_MAJOR_NV"/>
         <enum value="0x95B0" name="GL_SHADING_RATE_SAMPLE_ORDER_SAMPLE_MAJOR_NV"/>
-        <unused start="0x9581" end="0x962F" vendor="NV"/>
+        <unused start="0x95B1" end="0x95B2" vendor="NV"/>
+        <enum value="0x95B3" name="GL_SEMAPHORE_TYPE_NV"/>
+        <enum value="0x95B4" name="GL_SEMAPHORE_TYPE_BINARY_NV"/>
+        <enum value="0x95B5" name="GL_SEMAPHORE_TYPE_TIMELINE_NV"/>
+        <enum value="0x95B6" name="GL_MAX_TIMELINE_SEMAPHORE_VALUE_DIFFERENCE_NV"/>
+        <unused start="0x95B7" end="0x962F" vendor="NV"/>
     </enums>
 
     <enums namespace="GL" start="0x9630" end="0x963F" vendor="Oculus" comment="Email from Cass Everitt">
@@ -14967,6 +14973,11 @@
             <param len="n"><ptype>GLuint</ptype> *<name>samplers</name></param>
         </command>
         <command>
+            <proto>void <name>glCreateSemaphoresNV</name></proto>
+            <param><ptype>GLsizei</ptype> <name>n</name></param>
+            <param len="n"><ptype>GLuint</ptype> *<name>semaphores</name></param>
+        </command>
+        <command>
             <proto><ptype>GLuint</ptype> <name>glCreateShader</name></proto>
             <param group="ShaderType"><ptype>GLenum</ptype> <name>type</name></param>
         </command>
@@ -19710,6 +19721,12 @@
             <param len="COMPSIZE(pname)"><ptype>GLint</ptype> *<name>params</name></param>
         </command>
         <command>
+            <proto>void <name>glGetSemaphoreParameterivNV</name></proto>
+            <param><ptype>GLuint</ptype> <name>semaphore</name></param>
+            <param group="SemaphoreParameterName"><ptype>GLenum</ptype> <name>pname</name></param>
+            <param><ptype>GLint</ptype> *<name>params</name></param>
+        </command>
+        <command>
             <proto>void <name>glGetSemaphoreParameterui64vEXT</name></proto>
             <param><ptype>GLuint</ptype> <name>semaphore</name></param>
             <param group="SemaphoreParameterName"><ptype>GLenum</ptype> <name>pname</name></param>
@@ -27762,6 +27779,12 @@
             <param len="numCounters"><ptype>GLuint</ptype> *<name>counterList</name></param>
         </command>
         <command>
+            <proto>void <name>glSemaphoreParameterivNV</name></proto>
+            <param><ptype>GLuint</ptype> <name>semaphore</name></param>
+            <param group="SemaphoreParameterName"><ptype>GLenum</ptype> <name>pname</name></param>
+            <param>const <ptype>GLint</ptype> *<name>params</name></param>
+        </command>
+        <command>
             <proto>void <name>glSemaphoreParameterui64vEXT</name></proto>
             <param><ptype>GLuint</ptype> <name>semaphore</name></param>
             <param group="SemaphoreParameterName"><ptype>GLenum</ptype> <name>pname</name></param>
@@ -46839,6 +46862,18 @@
                 <command name="glTextureViewEXT"/>
             </require>
         </extension>
+        <extension name="GL_NV_timeline_semaphore" supported="gl|gles2">
+            <require>
+                <enum name="GL_TIMELINE_SEMAPHORE_VALUE_NV"/>
+                <enum name="GL_SEMAPHORE_TYPE_NV"/>
+                <enum name="GL_SEMAPHORE_TYPE_BINARY_NV"/>
+                <enum name="GL_SEMAPHORE_TYPE_TIMELINE_NV"/>
+                <enum name="GL_MAX_TIMELINE_SEMAPHORE_VALUE_DIFFERENCE_NV"/>
+                <command name="glCreateSemaphoresNV"/>
+                <command name="glSemaphoreParameterivNV"/>
+                <command name="glGetSemaphoreParameterivNV"/>
+            </require>
+        </extension>
         <extension name="GL_EXT_timer_query" supported="gl">
             <require>
                 <enum name="GL_TIME_ELAPSED_EXT"/>