| Name |
| |
| ARB_draw_indirect |
| |
| Name Strings |
| |
| GL_ARB_draw_indirect |
| |
| Contact |
| |
| Jeff Bolz, NVIDIA Corporation (jbolz 'at' nvidia.com) |
| Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com) |
| |
| Contributors |
| |
| Barthold Lichtenbelt, NVIDIA |
| Bill Licea-Kane, AMD |
| Bruce Merry, ARM |
| Graham Sellers, AMD |
| Greg Roth, NVIDIA |
| Nick Haemel, AMD |
| Pierre Boudier, AMD |
| Piers Daniell, NVIDIA |
| |
| Notice |
| |
| Copyright (c) 2010-2013 The Khronos Group Inc. Copyright terms at |
| http://www.khronos.org/registry/speccopyright.html |
| |
| Status |
| |
| Complete. Approved by the ARB at the 2010/01/22 F2F meeting. |
| Approved by the Khronos Board of Promoters on March 10, 2010. |
| |
| Version |
| |
| Last Modified Date: 09/17/2012 |
| Revision: 7 |
| |
| Number |
| |
| ARB Extension #87 |
| |
| Dependencies |
| |
| OpenGL 3.1 is required. |
| |
| This extension is written against the OpenGL 3.2 specification with |
| the Compatibility Profile. |
| |
| This extension interacts with NV_vertex_buffer_unified_memory. |
| |
| This extension interacts with ARB_instanced_arrays. |
| |
| This extension interacts with ARB_compatibility. |
| |
| Overview |
| |
| This extension provides a mechanism for supplying the arguments to a |
| DrawArraysInstanced or DrawElementsInstancedBaseVertex from buffer object |
| memory. This is not particularly useful for applications where the CPU |
| knows the values of the arguments beforehand, but is helpful when the |
| values will be generated on the GPU through any mechanism that can write |
| to a buffer object including image stores, atomic counters, or compute |
| interop. This allows the GPU to consume these arguments without a round- |
| trip to the CPU or the expensive synchronization that would involve. This |
| is similar to the DrawTransformFeedbackEXT command from |
| EXT_transform_feedback2, but offers much more flexibility in both |
| generating the arguments and in the type of Draws that can be accomplished. |
| |
| IP Status |
| |
| No known IP claims. |
| |
| New Procedures and Functions |
| |
| void DrawArraysIndirect(enum mode, const void *indirect); |
| void DrawElementsIndirect(enum mode, enum type, const void *indirect); |
| |
| New Tokens |
| |
| Accepted by the <target> parameters of BindBuffer, BufferData, |
| BufferSubData, MapBuffer, UnmapBuffer, GetBufferSubData, |
| GetBufferPointerv, MapBufferRange, FlushMappedBufferRange, |
| GetBufferParameteriv, and CopyBufferSubData: |
| |
| DRAW_INDIRECT_BUFFER 0x8F3F |
| |
| Accepted by the <value> parameter of GetIntegerv, GetBooleanv, GetFloatv, |
| and GetDoublev: |
| |
| DRAW_INDIRECT_BUFFER_BINDING 0x8F43 |
| |
| Additions to Chapter 2 of the OpenGL 3.2 Specification (OpenGL Operation) |
| |
| Add to Section 2.8.1 p. 40 (Drawing Commands) |
| |
| The command |
| |
| DrawArraysIndirect(enum mode, const void *indirect); |
| |
| behaves as follows: |
| |
| typedef struct { |
| GLuint count; |
| GLuint primCount; |
| GLuint first; |
| GLuint reservedMustBeZero; |
| } DrawArraysIndirectCommand; |
| |
| if (mode is invalid) { |
| generate appropriate error |
| } else { |
| DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *)indirect; |
| DrawArraysInstanced(mode, cmd->first, cmd->count, cmd->primCount); |
| } |
| |
| As with regular DrawArraysInstanced commands, the vertex attributes |
| may be sourced from client arrays or vertex buffer objects (if buffers |
| are bound). Unlike regular DrawArraysInstanced commands, the <first> |
| argument is unsigned and cannot cause an error. The results are undefined |
| if <reservedMustBeZero> is non-zero and may not result in program |
| termination. |
| |
| The command |
| |
| DrawElementsIndirect(enum mode, enum type, const void *indirect); |
| |
| behaves as follows: |
| |
| typedef struct { |
| GLuint count; |
| GLuint primCount; |
| GLuint firstIndex; |
| GLint baseVertex; |
| GLuint reservedMustBeZero; |
| } DrawElementsIndirectCommand; |
| |
| if (mode or type is invalid, or no index buffer) { |
| generate appropriate error |
| } else { |
| DrawElementsIndirectCommand *cmd = (DrawElementsIndirectCommand *)indirect; |
| |
| DrawElementsInstancedBaseVertex(mode, cmd->count, type, |
| cmd->firstIndex * size-of-type, cmd->primCount, cmd->baseVertex); |
| } |
| |
| As with regular DrawElementsInstancedBaseVertex commands, the vertex |
| attributes may be sourced from client arrays or vertex buffer objects |
| (if objects are bound). Unlike regular DrawElementsInstancedBaseVertex |
| commands, the indices may not come from a client array and must come from |
| an index buffer. If no element array buffer is bound, an INVALID_OPERATION |
| error is generated. The results are undefined if <reservedMustBeZero> is |
| non-zero and may not result in program termination. |
| |
| All elements of DrawArraysIndirectCommand and |
| DrawElementsIndirectCommand are 32bit values, and both structures are |
| tightly packed. |
| |
| Add to Section 2.9 (Buffer Objects) |
| |
| Add to Table 2.7 (p. 48): |
| |
| Target name Purpose Described in sections(s) |
| ----------------------- ---------- ------------------------- |
| DRAW_INDIRECT_BUFFER Indirect draw commands 2.9.9 |
| |
| Add a new Section 2.9.9 (Indirect Commands in Buffer Objects) |
| |
| Arguments to DrawArraysIndirect and DrawElementsIndirect commands |
| may be stored in buffer objects. |
| |
| Initially zero is bound to DRAW_INDIRECT_BUFFER. In the |
| compatibility profile, this indicates that DrawArraysIndirect and |
| DrawElementsIndirect are to source their arguments directly from the |
| pointer passed as their <indirect> parameters. In the core profile, |
| an INVALID_OPERATION error is generated if zero is bound to |
| DRAW_INDIRECT_BUFFER and DrawArraysIndirect or DrawElementsIndirect |
| is called. |
| |
| A buffer object is bound to DRAW_INDIRECT_BUFFER by calling |
| BindBuffer with <target> set to DRAW_INDIRECT_BUFFER, and <buffer> |
| set to the name of the buffer object. If no corresponding buffer |
| object exists, one is initialized as defined in section 2.9. |
| |
| While a non-zero buffer object name is bound to DRAW_INDIRECT_BUFFER, |
| DrawArraysIndirect and DrawElementsIndirect source their arguments |
| from that buffer object, using their <indirect> parameters as offsets |
| into the buffer object in the same fashion as described in section 2.9.3. |
| An INVALID_OPERATION error is generated if the commands source data |
| beyond the end of the buffer object or if <indirect> is not word aligned. |
| |
| Additions to Chapter 3 of the OpenGL 3.2 Specification (Rasterization) |
| |
| None. |
| |
| Additions to Chapter 4 of the OpenGL 3.2 Specification (Per-Fragment |
| Operations and the Frame Buffer) |
| |
| None. |
| |
| Additions to Chapter 5 of the OpenGL 3.2 Specification (Special Functions) |
| |
| None. |
| |
| Additions to Chapter 6 of the OpenGL 3.2 Specification (State and |
| State Requests) |
| |
| None. |
| |
| Additions to Appendix A of the OpenGL 3.2 Specification (Invariance) |
| |
| None. |
| |
| Additions to the AGL/GLX/WGL Specifications |
| |
| None. |
| |
| GLX Protocol |
| |
| TBD. |
| |
| Errors |
| |
| INVALID_ENUM is generated by DrawArraysIndirect/DrawElementsIndirect |
| if <mode> is not a valid begin mode. |
| |
| INVALID_ENUM is generated by DrawElementsIndirect if <type> is not |
| one of UNSIGNED_BYTE, UNSIGNED_SHORT, or UNSIGNED_INT. |
| |
| INVALID_OPERATION is generated by DrawElementsIndirect if no buffer |
| is bound to ELEMENT_ARRAY_BUFFER. |
| |
| INVALID_OPERATION is generated by DrawArraysIndirect and |
| DrawElementsIndirect if zero is bound to DRAW_INDIRECT_BUFFER and if |
| the OpenGL context implements the core profile. |
| |
| INVALID_OPERATION is generated by DrawArraysIndirect and |
| DrawElementsIndirect if commands source data beyond the end of a buffer |
| object or if <indirect> is not word aligned. |
| |
| New State |
| |
| Update Table 6.11, p. 405 (Vertex Array Data not in Vertex Array objects) |
| |
| Get Value Type Get Command Initial Value Sec Attribute |
| --------- ---- ----------- ------------- --- --------- |
| DRAW_INDIRECT_BUFFER_BINDING Z+ GetIntegerv 0 2.9 none |
| |
| New Implementation Dependent State |
| |
| None. |
| |
| Dependencies on NV_vertex_buffer_unified_memory |
| |
| If NV_vertex_buffer_unified_memory is supported, the following additional |
| edits are required: |
| |
| Accepted by the <cap> parameter of GetBufferParameterui64vNV: |
| |
| DRAW_INDIRECT_BUFFER. |
| |
| Accepted by the <cap> parameter of DisableClientState, |
| EnableClientState, IsEnabled: |
| |
| DRAW_INDIRECT_UNIFIED_NV 0x8F40 |
| |
| Accepted by the <pname> parameter of BufferAddressRangeNV |
| and the <value> parameter of GetIntegerui64vNV: |
| |
| DRAW_INDIRECT_ADDRESS_NV 0x8F41 |
| |
| Accepted by the <value> parameter of GetIntegerv: |
| |
| DRAW_INDIRECT_LENGTH_NV 0x8F42 |
| |
| In Section 2.8.1, mention that vertex attributes and indices may be |
| sourced from GPU addresses if VERTEX_ATTRIB_ARRAY_UNIFIED_NV/ |
| ELEMENT_ARRAY_UNIFIED_NV are enabled. |
| |
| Add to Section 2.9: |
| |
| While DRAW_INDIRECT_UNIFIED_NV is enabled, DrawArraysIndirect and |
| DrawElementsIndirect, source their arguments from the address |
| specified by the command BufferAddressRange where <pname> is |
| DRAW_INDIRECT_ADDRESS_NV and <index> is zero, added to the <indirect> |
| parameter. If the commands source data beyond and including (<address> |
| + <length>), an INVALID_OPERATION error will be generated. If the draw |
| indirect address range does not belong to a buffer object that is |
| resident at the time of the Draw, undefined results, possibly |
| including program termination, may occur. |
| |
| INVALID_OPERATION is generated by DrawElementsIndirect if no buffer |
| is bound to ELEMENT_ARRAY_BUFFER and DRAW_INDIRECT_UNIFIED_NV is |
| disabled. |
| |
| INVALID_OPERATION is generated by DrawArraysIndirect and |
| DrawElementsIndirect if DRAW_INDIRECT_UNIFIED_NV is enabled and |
| commands source data beyond and including (address + length). |
| |
| Update Table 6.11: |
| |
| Get Value Type Get Command Initial Value Sec Attribute |
| --------- ---- ----------- ------------- --- --------- |
| DRAW_INDIRECT_UNIFIED_NV B IsEnabled FALSE 2.9 none |
| DRAW_INDIRECT_ADDRESS_NV Z64+ GetIntegerui64vNV 0 2.9 none |
| DRAW_INDIRECT_LENGTH_NV Z+ GetIntegerv 0 2.9 none |
| |
| Dependencies on NV_vertex_buffer_unified_memory and ARB_compatibility |
| |
| If the context version is greater than 3.0 and does not include |
| ARB_compatibility functionality, then EnableClientState and |
| DisableClientState have been deprecated and removed. This extension |
| adds back those commands if NV_vertex_buffer_unified_memory is supported, |
| but only requires that they accept the DRAW_INDIRECT_UNIFIED_NV token. |
| |
| Dependencies on ARB_compatibility |
| |
| When the ARB_compatibility extension is not supported, client arrays |
| cannot be used to source vertex attribute data. |
| |
| Dependencies on ARB_instanced_arrays |
| |
| This extension does not require ARB_instanced_arrays, but reserves |
| space in the Command structures such that a future extension could |
| add a "firstInstance" member which would initialize the instance |
| counter used for computing which vertex attrib array element to use. |
| Note that ARB_instanced_arrays does not currently support |
| "firstInstance", it only has a frequency divider. |
| |
| Issues |
| |
| (1) What is this good for? |
| |
| RESOLVED: Compute interoperability. Recirculating results written via |
| image stores or atomic counters. |
| |
| (2) Should we allow indirect draws from client memory? Should we have a |
| buffer object binding for this? |
| |
| RESOLVED: YES. Although, using client vertex arrays would somewhat defeat |
| the purpose of this extension. Note that this issue only applies to |
| implementations supporting the ARB_compatibility extension. |
| |
| One non-obvious restriction is that DrawElementsIndirect doesn't accept |
| an <indices> parameter, so an index buffer is required. |
| |
| (3) How do we specify the index size for DrawElements calls? |
| |
| RESOLVED: Passed into the command, not pulled out of the struct. |
| |
| (4) For DrawElements calls, in what unit are the offsets into the index |
| buffer. |
| |
| RESOLVED: In indices, not in bytes. |
| |
| (5) Should the new state be part of the VAO? |
| |
| RESOLVED: No. |
| |
| (6) Should gl.h/glext.h provide structure definitions? |
| |
| RESOLVED. No. It is not possible to define the structures in such a way |
| that all compilers would pack them correctly. |
| |
| Revision History |
| |
| Rev. Date Author Changes |
| ---- -------- -------- ------------------------------------------------ |
| 7 09/17/2012 Jon Leech Remove BindBufferRange/Base from commands for |
| which DRAW_INDIRECT_BUFFER is a valid target |
| (Bug 7794). |
| |
| 6 03/07/2012 Jon Leech Add missing error when no indirect buffer is |
| bound and the indirect draw commands are |
| called (Bug 7211). |
| |
| 5 12/07/2009 pdaniell Remove ARB suffix from new tokens for core spec. |
| |
| 4 10/29/2009 pdaniell Convert to ARB. |
| |
| 3 10/21/2009 pdaniell Minor edits based on Bruce's feedback. Added |
| full list of Get* calls for new |
| DRAW_INDIRECT_BUFFER_BINDING_EXT token. |
| Specified behavior when reservedMustBeZero is |
| non-zero. Added INVALID_VALUE error when |
| <indirect> is not a multiple of GLuint. |
| |
| 2 jbolz Internal revisions. |
| |
| 1 pbrown Internal revisions. |