Name EXT_direct_state_access Name Strings GL_EXT_direct_state_access Contributors Cass Everitt, NVIDIA Daniel Pageau, Blizzard Daniel Koch, TransGaming Ian Romanick, IBM Jason Green, TransGaming Johan Andersson, DICE/Electronic Arts Jon Leech Mark Kilgard, NVIDIA Nicholas Vining, Destineer Pat Brown, NVIDIA Patrick Doane, Blizzard Robert Barris, Blizzard Ryan Gordon, Destineer Scott Nations, NVIDIA Yanjun Zhang, S3 Graphics Jeff Bolz, NVIDIA Jeff Juliano, NVIDIA Jon Burgess, NVIDIA Mike Marcin Nigel Stewart, NVIDIA Jason McKesson Graham Sellers, AMD Vladimir Vukicevic, Mozilla Contact Mark J. Kilgard, NVIDIA Corporation (mjk 'at' nvidia.com) Status Complete, except for GLX protocol Version 1.0 implemented by NVIDIA, shipping November 2008 Version 1.1 implemented by NVIDIA, shipping January 2009 Version Last Modified Date: 02/24/2014 Author revision: 39 Version 1.2 (version 1.0 lacked OpenGL 3.0 support) (version 1.1 lacked GL_TEXTUREi support for glVertexArrayTexCoordOffsetEXT) (version 1.1 didn't clearly specify GL_TEXTURE_COORD_ARRAY works with glGetVertexArrayIntegeri_vEXT) Number 353 Dependencies This extension is written against the OpenGL 2.1 specification. This extension interacts with the matrix manipulation commands introduced by OpenGL 1.0. This extension interacts with the texture object manipulation commands introduced by EXT_texture_object and standardized by OpenGL 1.1. This extension interacts with the 3D texture object manipulation commands introduced by EXT_texture3D and standardized by OpenGL 1.2. This extension interacts with the multitexture command introduced by ARB_multitexture and standardized by OpenGL 1.2.1. This extension interacts with the matrix transpose manipulation commands introduced by ARB_transpose_matrix and standardized by OpenGL 1.3. This extension interacts with the local parameter program object manipulation commands introduced by ARB_vertex_program. This extension interacts with the texture rectangle enable and target binding introduced by ARB_texture_rectangle (and NV_texture_rectangle and EXT_texture_rectangle). This extension interacts with the buffer manipulation commands standardized by OpenGL 1.5. This extension interacts with the GLSL uniform commands standardized by OpenGL 2.0. This extension interacts with the GLSL uniform matrix commands standardized by OpenGL 2.1. This extension interacts with the framebuffer object commands introduced by EXT_framebuffer_object and standardized by OpenGL 3.0. This extension interacts with the framebuffer blit commands introduced by EXT_framebuffer_blit and standardized by OpenGL 3.0. This extension interacts with the framebuffer multisample commands introduced by EXT_framebuffer_multisample and standardized by OpenGL 3.0. This extension interacts with the vertex array object commands introduced by APPLE_vertex_array_object and standardized by OpenGL 3.0. This extension interacts with the integer texture parameter commands introduced by EXT_texture_integer and standardized by OpenGL 3.0. This extension interacts with the texture buffer commands introduced by EXT_texture_buffer_object. This extension interacts with the GLSL integer uniform commands introduced by EXT_gpu_shader4. This extension interacts with the local plural parameter program object manipulation commands introduced by EXT_gpu_program_parameters. This extension interacts with the local integer parameter program object manipulation commands introduced by NV_gpu_program4. This extension trivially interacts with the EnableIndexedEXT and DisableIndexed commands and the integer and boolean indexed queries introduced by EXT_draw_buffers2, EXT_transform_feedback, and NV_transform_feedback. This extension interacts with NV_explicit_multisample. This extension trivially interacts with EXT_texture_array. This extension trivially interacts with NV_texture_cube_map_array. This extension interacts with the buffer data copying command introduced by EXT_copy_buffer and standardized by OpenGL 3.0. Overview This extension introduces a set of new "direct state access" commands (meaning no selector is involved) to access (update and query) OpenGL state that previously depended on the OpenGL state selectors for access. These new commands supplement the existing selector-based OpenGL commands to access the same state. The intent of this extension is to make it more efficient for libraries to avoid disturbing selector and latched state. The extension also allows more efficient command usage by eliminating the need for selector update commands. Two derivative advantages of this extension are 1) display lists can be executed using these commands that avoid disturbing selectors that subsequent commands may depend on, and 2) drivers implemented with a dual-thread partitioning with OpenGL command buffering from an application thread and then OpenGL command dispatching in a concurrent driver thread can avoid thread synchronization created by selector saving, setting, command execution, and selector restoration. This extension does not itself add any new OpenGL state. We call a state variable in OpenGL an "OpenGL state selector" or simply a "selector" if OpenGL commands depend on the state variable to determine what state to query or update. The matrix mode and active texture are both selectors. Object bindings for buffers, programs, textures, and framebuffer objects are also selectors. We call OpenGL state "latched" if the state is set by one OpenGL command but then that state is saved by a subsequent command or the state determines how client memory or buffer object memory is accessed by a subsequent command. The array and element array buffer bindings are latched by vertex array specification commands to determine which buffer a given vertex array uses. Vertex array state and pixel pack/unpack state decides how client memory or buffer object memory is accessed by subsequent vertex pulling or image specification commands. The existence of selectors and latched state in the OpenGL API reduces the number of parameters to various sets of OpenGL commands but complicates the access to state for layered libraries which seek to access state without disturbing other state, namely the state of state selectors and latched state. In many cases, selectors and latched state were introduced by extensions as OpenGL evolved to minimize the disruption to the OpenGL API when new functionality, particularly the pluralization of existing functionality as when texture objects and later multiple texture units, was introduced. The OpenGL API involves several selectors (listed in historical order of introduction): o The matrix mode. o The current bound texture for each supported texture target. o The active texture. o The active client texture. o The current bound program for each supported program target. o The current bound buffer for each supported buffer target. o The current GLSL program. o The current framebuffer object. The new selector-free update commands can be compiled into display lists. The OpenGL API has latched state for vertex array buffer objects and pixel store state. When an application issues a GL command to unpack or pack pixels (for example, glTexImage2D or glReadPixels respectively), the current unpack and pack pixel store state determines how the pixels are unpacked from/packed to client memory or pixel buffer objects. For example, consider: glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); glPixelStorei(GL_UNPACK_ROW_LENGTH, 640); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 47); glDrawPixels(100, 100, GL_RGB, GL_FLOAT, pixels); The unpack swap bytes and row length state set by the preceding glPixelStorei commands (as well as the 6 other unpack pixel store state variables) control how data is read (unpacked) from buffer of data pointed to by pixels. The glBindBuffer command also specifies an unpack buffer object (47) so the pixel pointer is actually treated as a byte offset into buffer object 47. When an application issues a command to configure a vertex array, the current array buffer state is latched as the binding for the particular vertex array being specified. For example, consider: glBindBuffer(GL_ARRAY_BUFFER, 23); glVertexPointer(3, GL_FLOAT, 12, pointer); The glBindBuffer command updates the array buffering binding (GL_ARRAY_BUFFER_BINDING) to the buffer object named 23. The subsequent glVertexPointer command specifies explicit parameters for the size, type, stride, and pointer to access the position vertex array BUT ALSO latches the current array buffer binding for the vertex array buffer binding (GL_VERTEX_ARRAY_BUFFER_BINDING). Effectively the current array buffer binding buffer object becomes an implicit fifth parameter to glVertexPointer and this applies to all the gl*Pointer vertex array specification commands. Selectors and latched state create problems for layered libraries using OpenGL because selectors require the selector state to be modified to update some other state and latched state means implicit state can affect the operation of commands specifying, packing, or unpacking data through pointers/offsets. For layered libraries, a state update performed by the library may attempt to save the selector state, set the selector, update/query some state the selector controls, and then restore the selector to its saved state. Layered libraries can skip the selector save/restore but this risks introducing uncertainty about the state of a selector after calling layered library routines. Such selector side-effects are difficult to document and lead to compatibility issues as the layered library evolves or its usage varies. For latched state, layered libraries may find commands such as glDrawPixels do not work as expected because latched pixel store state is not what the library expects. Querying or pushing the latched state, setting the latched state explicitly, performing the operation involving latched state, and then restoring or popping the latched state avoids entanglements with latched state but at considerable cost. EXAMPLE USAGE OF THIS EXTENSION'S FUNCTIONALITY Consider the following routine to set the modelview matrix involving the matrix mode selector: void setModelviewMatrix(const GLfloat matrix[16]) { GLenum savedMatrixMode; glGetIntegerv(GL_MATRIX_MODE, &savedMatrixMode); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(matrix); glMatrixMode(savedMatrixMode); } Notice that four OpenGL commands are required to update the current modelview matrix without disturbing the matrix mode selector. OpenGL query commands can also substantially reduce the performance of modern OpenGL implementations which may off-load OpenGL state processing to another CPU core/thread or to the GPU itself. An alternative to querying the selector is to use the glPushAttrib/glPopAttrib commands. However this approach typically involves pushing far more state than simply the one or two selectors that need to be saved and restored. Because so much state is associated with a given push/pop attribute bit, the glPushAttrib and glPopAttrib commands are considerably more costly than the save/restore approach. Additionally glPushAttrib risks overflowing the attribute stack. The reliability and performance of layered libraries and applications can be improved by adding to the OpenGL API a new set of commands to access directly OpenGL state that otherwise involves selectors to access. The above example can be reimplemented more efficiently and without selector side-effects: void setModelviewMatrix(const GLfloat matrix[16]) { glMatrixLoadfEXT(GL_MODELVIEW, matrix); } Consider a layered library seeking to load a texture: void loadTexture(GLint texobj, GLint width, GLint height, void *data) { glBindTexture(GL_TEXTURE_2D, texobj); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height, GL_RGB, GL_FLOAT, data); } The library expects the data to be packed into the buffer pointed to by data. But what if the current pixel unpack buffer binding is not zero so the current pixel unpack buffer, rather than client memory, will be read? Or what if the application has modified the GL_UNPACK_ROW_LENGTH pixel store state before loadTexture is called? We can fix the routine by calling glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0) and setting all the pixel store unpack state to the initial state the loadTexture routine expects, but this is expensive. It also risks disturbing the state so when loadTexture returns to the application, the application doesn't realize the current texture object (for whatever texture unit the current active texture happens to be) and pixel store state has changed. We can more efficiently implement this routine without disturbing selector or latched state as follows: void loadTexture(GLint texobj, GLint width, GLint height, void *data) { glPushClientAttribDefaultEXT(GL_CLIENT_PIXEL_STORE_BIT); glTextureImage2D(texobj, GL_TEXTURE_2D, 0, GL_RGB8, width, height, GL_RGB, GL_FLOAT, data); glPopClientAttrib(); } Now loadTexture does not have to worry about inappropriately configured pixel store state or a non-zero pixel unpack buffer binding. And loadTexture has no unintended side-effects for selector or latched state (assuming the client attrib state does not overflow). New Procedures and Functions void ClientAttribDefaultEXT(bitfield mask); void PushClientAttribDefaultEXT(bitfield mask); void MatrixLoadfEXT(enum matrixMode, const float *m); void MatrixLoaddEXT(enum matrixMode, const double *m); void MatrixMultfEXT(enum matrixMode, const float *m); void MatrixMultdEXT(enum matrixMode, const double *m); void MatrixLoadIdentityEXT(enum matrixMode); void MatrixRotatefEXT(enum matrixMode, float angle, float x, float y, float z); void MatrixRotatedEXT(enum matrixMode, double angle, double x, double y, double z); void MatrixScalefEXT(enum matrixMode, float x, float y, float z); void MatrixScaledEXT(enum matrixMode, double x, double y, double z); void MatrixTranslatefEXT(enum matrixMode, float x, float y, float z); void MatrixTranslatedEXT(enum matrixMode, double x, double y, double z); void MatrixOrthoEXT(enum matrixMode, double l, double r, double b, double t, double n, double f); void MatrixFrustumEXT(enum matrixMode, double l, double r, double b, double t, double n, double f); void MatrixPushEXT(enum matrixMode); void MatrixPopEXT(enum matrixMode); void TextureParameteriEXT(uint texture, enum target, enum pname, int param); void TextureParameterivEXT(uint texture, enum target, enum pname, const int *param); void TextureParameterfEXT(uint texture, enum target, enum pname, float param); void TextureParameterfvEXT(uint texture, enum target, enum pname, const float *param); void TextureImage1DEXT(uint texture, enum target, int level, int internalformat, sizei width, int border, enum format, enum type, const void *pixels); void TextureImage2DEXT(uint texture, enum target, int level, int internalformat, sizei width, sizei height, int border, enum format, enum type, const void *pixels); void TextureSubImage1DEXT(uint texture, enum target, int level, int xoffset, sizei width, enum format, enum type, const void *pixels); void TextureSubImage2DEXT(uint texture, enum target, int level, int xoffset, int yoffset, sizei width, sizei height, enum format, enum type, const void *pixels); void CopyTextureImage1DEXT(uint texture, enum target, int level, enum internalformat, int x, int y, sizei width, int border); void CopyTextureImage2DEXT(uint texture, enum target, int level, enum internalformat, int x, int y, sizei width, sizei height, int border); void CopyTextureSubImage1DEXT(uint texture, enum target, int level, int xoffset, int x, int y, sizei width); void CopyTextureSubImage2DEXT(uint texture, enum target, int level, int xoffset, int yoffset, int x, int y, sizei width, sizei height); void GetTextureImageEXT(uint texture, enum target, int level, enum format, enum type, void *pixels); void GetTextureParameterfvEXT(uint texture, enum target, enum pname, float *params); void GetTextureParameterivEXT(uint texture, enum target, enum pname, int *params); void GetTextureLevelParameterfvEXT(uint texture, enum target, int level, enum pname, float *params); void GetTextureLevelParameterivEXT(uint texture, enum target, int level, enum pname, int *params); void TextureImage3DEXT(uint texture, enum target, int level, int internalformat, sizei width, sizei height, sizei depth, int border, enum format, enum type, const void *pixels); void TextureSubImage3DEXT(uint texture, enum target, int level, int xoffset, int yoffset, int zoffset, sizei width, sizei height, sizei depth, enum format, enum type, const void *pixels); void CopyTextureSubImage3DEXT(uint texture, enum target, int level, int xoffset, int yoffset, int zoffset, int x, int y, sizei width, sizei height); void BindMultiTextureEXT(enum texunit, enum target, uint texture); void MultiTexCoordPointerEXT(enum texunit, int size, enum type, sizei stride, const void *pointer); void MultiTexEnvfEXT(enum texunit, enum target, enum pname, float param); void MultiTexEnvfvEXT(enum texunit, enum target, enum pname, const float *params); void MultiTexEnviEXT(enum texunit, enum target, enum pname, int param); void MultiTexEnvivEXT(enum texunit, enum target, enum pname, const int *params); void MultiTexGendEXT(enum texunit, enum coord, enum pname, double param); void MultiTexGendvEXT(enum texunit, enum coord, enum pname, const double *params); void MultiTexGenfEXT(enum texunit, enum coord, enum pname, float param); void MultiTexGenfvEXT(enum texunit, enum coord, enum pname, const float *params); void MultiTexGeniEXT(enum texunit, enum coord, enum pname, int param); void MultiTexGenivEXT(enum texunit, enum coord, enum pname, const int *params); void GetMultiTexEnvfvEXT(enum texunit, enum target, enum pname, float *params); void GetMultiTexEnvivEXT(enum texunit, enum target, enum pname, int *params); void GetMultiTexGendvEXT(enum texunit, enum coord, enum pname, double *params); void GetMultiTexGenfvEXT(enum texunit, enum coord, enum pname, float *params); void GetMultiTexGenivEXT(enum texunit, enum coord, enum pname, int *params); void MultiTexParameteriEXT(enum texunit, enum target, enum pname, int param); void MultiTexParameterivEXT(enum texunit, enum target, enum pname, const int *param); void MultiTexParameterfEXT(enum texunit, enum target, enum pname, float param); void MultiTexParameterfvEXT(enum texunit, enum target, enum pname, const float *param); void MultiTexImage1DEXT(enum texunit, enum target, int level, int internalformat, sizei width, int border, enum format, enum type, const void *pixels); void MultiTexImage2DEXT(enum texunit, enum target, int level, int internalformat, sizei width, sizei height, int border, enum format, enum type, const void *pixels); void MultiTexSubImage1DEXT(enum texunit, enum target, int level, int xoffset, sizei width, enum format, enum type, const void *pixels); void MultiTexSubImage2DEXT(enum texunit, enum target, int level, int xoffset, int yoffset, sizei width, sizei height, enum format, enum type, const void *pixels); void CopyMultiTexImage1DEXT(enum texunit, enum target, int level, enum internalformat, int x, int y, sizei width, int border); void CopyMultiTexImage2DEXT(enum texunit, enum target, int level, enum internalformat, int x, int y, sizei width, sizei height, int border); void CopyMultiTexSubImage1DEXT(enum texunit, enum target, int level, int xoffset, int x, int y, sizei width); void CopyMultiTexSubImage2DEXT(enum texunit, enum target, int level, int xoffset, int yoffset, int x, int y, sizei width, sizei height); void GetMultiTexImageEXT(enum texunit, enum target, int level, enum format, enum type, void *pixels); void GetMultiTexParameterfvEXT(enum texunit, enum target, enum pname, float *params); void GetMultiTexParameterivEXT(enum texunit, enum target, enum pname, int *params); void GetMultiTexLevelParameterfvEXT(enum texunit, enum target, int level, enum pname, float *params); void GetMultiTexLevelParameterivEXT(enum texunit, enum target, int level, enum pname, int *params); void MultiTexImage3DEXT(enum texunit, enum target, int level, int internalformat, sizei width, sizei height, sizei depth, int border, enum format, enum type, const void *pixels); void MultiTexSubImage3DEXT(enum texunit, enum target, int level, int xoffset, int yoffset, int zoffset, sizei width, sizei height, sizei depth, enum format, enum type, const void *pixels); void CopyMultiTexSubImage3DEXT(enum texunit, enum target, int level, int xoffset, int yoffset, int zoffset, int x, int y, sizei width, sizei height); void EnableClientStateIndexedEXT(enum array, uint index); void DisableClientStateIndexedEXT(enum array, uint index); void EnableClientStateiEXT(enum array, uint index); void DisableClientStateiEXT(enum array, uint index); void GetFloatIndexedvEXT(enum target, uint index, float *params); void GetDoubleIndexedvEXT(enum target, uint index, double *params); void GetPointerIndexedvEXT(enum target, uint index, void **params); void GetFloati_vEXT(enum pname, uint index, float *params); void GetDoublei_vEXT(enum pname, uint index, double *params); void GetPointeri_vEXT(enum pname, uint index, void **params); void EnableIndexedEXT(enum cap, uint index); void DisableIndexedEXT(enum cap, uint index); boolean IsEnabledIndexedEXT(enum target, uint index); void GetIntegerIndexedvEXT(enum target, uint index, int *params); void GetBooleanIndexedvEXT(enum target, uint index, boolean *params); void NamedProgramStringEXT(uint program, enum target, enum format, sizei len, const void *string); void NamedProgramLocalParameter4dEXT(uint program, enum target, uint index, double x, double y, double z, double w); void NamedProgramLocalParameter4dvEXT(uint program, enum target, uint index, const double *params); void NamedProgramLocalParameter4fEXT(uint program, enum target, uint index, float x, float y, float z, float w); void NamedProgramLocalParameter4fvEXT(uint program, enum target, uint index, const float *params); void GetNamedProgramLocalParameterdvEXT(uint program, enum target, uint index, double *params); void GetNamedProgramLocalParameterfvEXT(uint program, enum target, uint index, float *params); void GetNamedProgramivEXT(uint program, enum target, enum pname, int *params); void GetNamedProgramStringEXT(uint program, enum target, enum pname, void *string); void CompressedTextureImage3DEXT(uint texture, enum target, int level, enum internalformat, sizei width, sizei height, sizei depth, int border, sizei imageSize, const void *data); void CompressedTextureImage2DEXT(uint texture, enum target, int level, enum internalformat, sizei width, sizei height, int border, sizei imageSize, const void *data); void CompressedTextureImage1DEXT(uint texture, enum target, int level, enum internalformat, sizei width, int border, sizei imageSize, const void *data); void CompressedTextureSubImage3DEXT(uint texture, enum target, int level, int xoffset, int yoffset, int zoffset, sizei width, sizei height, sizei depth, enum format, sizei imageSize, const void *data); void CompressedTextureSubImage2DEXT(uint texture, enum target, int level, int xoffset, int yoffset, sizei width, sizei height, enum format, sizei imageSize, const void *data); void CompressedTextureSubImage1DEXT(uint texture, enum target, int level, int xoffset, sizei width, enum format, sizei imageSize, const void *data); void GetCompressedTextureImageEXT(uint texture, enum target, int level, void *img); void CompressedMultiTexImage3DEXT(enum texunit, enum target, int level, enum internalformat, sizei width, sizei height, sizei depth, int border, sizei imageSize, const void *data); void CompressedMultiTexImage2DEXT(enum texunit, enum target, int level, enum internalformat, sizei width, sizei height, int border, sizei imageSize, const void *data); void CompressedMultiTexImage1DEXT(enum texunit, enum target, int level, enum internalformat, sizei width, int border, sizei imageSize, const void *data); void CompressedMultiTexSubImage3DEXT(enum texunit, enum target, int level, int xoffset, int yoffset, int zoffset, sizei width, sizei height, sizei depth, enum format, sizei imageSize, const void *data); void CompressedMultiTexSubImage2DEXT(enum texunit, enum target, int level, int xoffset, int yoffset, sizei width, sizei height, enum format, sizei imageSize, const void *data); void CompressedMultiTexSubImage1DEXT(enum texunit, enum target, int level, int xoffset, sizei width, enum format, sizei imageSize, const void *data); void GetCompressedMultiTexImageEXT(enum texunit, enum target, int level, void *img); void MatrixLoadTransposefEXT(enum matrixMode, const float *m); void MatrixLoadTransposedEXT(enum matrixMode, const double *m); void MatrixMultTransposefEXT(enum matrixMode, const float *m); void MatrixMultTransposedEXT(enum matrixMode, const double *m); void NamedBufferDataEXT(uint buffer, sizeiptr size, const void *data, enum usage); void NamedBufferSubDataEXT(uint buffer, intptr offset, sizeiptr size, const void *data); void* MapNamedBufferEXT(uint buffer, enum access); boolean UnmapNamedBufferEXT(uint buffer); void GetNamedBufferParameterivEXT(uint buffer, enum pname, int *params); void GetNamedBufferPointervEXT(uint buffer, enum pname, void* *params); void GetNamedBufferSubDataEXT(uint buffer, intptr offset, sizeiptr size, void *data); void ProgramUniform1fEXT(uint program, int location, float v0); void ProgramUniform2fEXT(uint program, int location, float v0, float v1); void ProgramUniform3fEXT(uint program, int location, float v0, float v1, float v2); void ProgramUniform4fEXT(uint program, int location, float v0, float v1, float v2, float v3); void ProgramUniform1iEXT(uint program, int location, int v0); void ProgramUniform2iEXT(uint program, int location, int v0, int v1); void ProgramUniform3iEXT(uint program, int location, int v0, int v1, int v2); void ProgramUniform4iEXT(uint program, int location, int v0, int v1, int v2, int v3); void ProgramUniform1fvEXT(uint program, int location, sizei count, const float *value); void ProgramUniform2fvEXT(uint program, int location, sizei count, const float *value); void ProgramUniform3fvEXT(uint program, int location, sizei count, const float *value); void ProgramUniform4fvEXT(uint program, int location, sizei count, const float *value); void ProgramUniform1ivEXT(uint program, int location, sizei count, const int *value); void ProgramUniform2ivEXT(uint program, int location, sizei count, const int *value); void ProgramUniform3ivEXT(uint program, int location, sizei count, const int *value); void ProgramUniform4ivEXT(uint program, int location, sizei count, const int *value); void ProgramUniformMatrix2fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniformMatrix3fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniformMatrix4fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniformMatrix2x3fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniformMatrix3x2fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniformMatrix2x4fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniformMatrix4x2fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniformMatrix3x4fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniformMatrix4x3fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void TextureBufferEXT(uint texture, enum target, enum internalformat, uint buffer); void MultiTexBufferEXT(enum texunit, enum target, enum internalformat, uint buffer); void TextureParameterIivEXT(uint texture, enum target, enum pname, const int *params); void TextureParameterIuivEXT(uint texture, enum target, enum pname, const uint *params); void GetTextureParameterIivEXT(uint texture, enum target, enum pname, int *params); void GetTextureParameterIuivEXT(uint texture, enum target, enum pname, uint *params); void MultiTexParameterIivEXT(enum texunit, enum target, enum pname, const int *params); void MultiTexParameterIuivEXT(enum texunit, enum target, enum pname, const uint *params); void GetMultiTexParameterIivEXT(enum texunit, enum target, enum pname, int *params); void GetMultiTexParameterIuivEXT(enum texunit, enum target, enum pname, uint *params); void ProgramUniform1uiEXT(uint program, int location, uint v0); void ProgramUniform2uiEXT(uint program, int location, uint v0, uint v1); void ProgramUniform3uiEXT(uint program, int location, uint v0, uint v1, uint v2); void ProgramUniform4uiEXT(uint program, int location, uint v0, uint v1, uint v2, uint v3); void ProgramUniform1uivEXT(uint program, int location, sizei count, const uint *value); void ProgramUniform2uivEXT(uint program, int location, sizei count, const uint *value); void ProgramUniform3uivEXT(uint program, int location, sizei count, const uint *value); void ProgramUniform4uivEXT(uint program, int location, sizei count, const uint *value); void NamedProgramLocalParameters4fvEXT(uint program, enum target, uint index, sizei count, const float *params); void NamedProgramLocalParameterI4iEXT(uint program, enum target, uint index, int x, int y, int z, int w); void NamedProgramLocalParameterI4ivEXT(uint program, enum target, uint index, const int *params); void NamedProgramLocalParametersI4ivEXT(uint program, enum target, uint index, sizei count, const int *params); void NamedProgramLocalParameterI4uiEXT(uint program, enum target, uint index, uint x, uint y, uint z, uint w); void NamedProgramLocalParameterI4uivEXT(uint program, enum target, uint index, const uint *params); void NamedProgramLocalParametersI4uivEXT(uint program, enum target, uint index, sizei count, const uint *params); void GetNamedProgramLocalParameterIivEXT(uint program, enum target, uint index, int *params); void GetNamedProgramLocalParameterIuivEXT(uint program, enum target, uint index, uint *params); void NamedRenderbufferStorageEXT(uint renderbuffer, enum internalformat, sizei width, sizei height); void GetNamedRenderbufferParameterivEXT(uint renderbuffer, enum pname, int *params); void NamedRenderbufferStorageMultisampleEXT(uint renderbuffer, sizei samples, enum internalformat, sizei width, sizei height); void NamedRenderbufferStorageMultisampleCoverageEXT(uint renderbuffer, sizei coverageSamples, sizei colorSamples, enum internalformat, sizei width, sizei height); enum CheckNamedFramebufferStatusEXT(uint framebuffer, enum target); void NamedFramebufferTexture1DEXT(uint framebuffer, enum attachment, enum textarget, uint texture, int level); void NamedFramebufferTexture2DEXT(uint framebuffer, enum attachment, enum textarget, uint texture, int level); void NamedFramebufferTexture3DEXT(uint framebuffer, enum attachment, enum textarget, uint texture, int level, int zoffset); void NamedFramebufferRenderbufferEXT(uint framebuffer, enum attachment, enum renderbuffertarget, uint renderbuffer); void GetNamedFramebufferAttachmentParameterivEXT(uint framebuffer, enum attachment, enum pname, int *params); void GenerateTextureMipmapEXT(uint texture, enum target); void GenerateMultiTexMipmapEXT(enum texunit, enum target); void FramebufferDrawBufferEXT(uint framebuffer, enum mode); void FramebufferDrawBuffersEXT(uint framebuffer, sizei n, const enum *bufs) void FramebufferReadBufferEXT(uint framebuffer, enum mode); void GetFramebufferParameterivEXT(uint framebuffer, enum pname, int *param); void NamedCopyBufferSubDataEXT(uint readBuffer, uint writeBuffer, intptr readOffset, intptr writeOffset, sizeiptr size); void NamedFramebufferTextureEXT(uint framebuffer, enum attachment, uint texture, int level); void NamedFramebufferTextureLayerEXT(uint framebuffer, enum attachment, uint texture, int level, int layer); void NamedFramebufferTextureFaceEXT(uint framebuffer, enum attachment, uint texture, int level, enum face); void TextureRenderbufferEXT(uint texture, enum target, uint renderbuffer); void MultiTexRenderbufferEXT(enum texunit, enum target, uint renderbuffer); void VertexArrayVertexOffsetEXT(uint vaobj, uint buffer, int size, enum type, sizei stride, intptr offset); void VertexArrayColorOffsetEXT(uint vaobj, uint buffer, int size, enum type, sizei stride, intptr offset); void VertexArrayEdgeFlagOffsetEXT(uint vaobj, uint buffer, sizei stride, intptr offset); void VertexArrayIndexOffsetEXT(uint vaobj, uint buffer, enum type, sizei stride, intptr offset); void VertexArrayNormalOffsetEXT(uint vaobj, uint buffer, enum type, sizei stride, intptr offset); void VertexArrayTexCoordOffsetEXT(uint vaobj, uint buffer, int size, enum type, sizei stride, intptr offset); void VertexArrayMultiTexCoordOffsetEXT(uint vaobj, uint buffer, enum texunit, int size, enum type, sizei stride, intptr offset); void VertexArrayFogCoordOffsetEXT(uint vaobj, uint buffer, enum type, sizei stride, intptr offset); void VertexArraySecondaryColorOffsetEXT(uint vaobj, uint buffer, int size, enum type, sizei stride, intptr offset); void VertexArrayVertexAttribOffsetEXT(uint vaobj, uint buffer, uint index, int size, enum type, boolean normalized, sizei stride, intptr offset); void VertexArrayVertexAttribIOffsetEXT(uint vaobj, uint buffer, uint index, int size, enum type, sizei stride, intptr offset); void EnableVertexArrayEXT(uint vaobj, enum array); void DisableVertexArrayEXT(uint vaobj, enum array); void EnableVertexArrayAttribEXT(uint vaobj, uint index); void DisableVertexArrayAttribEXT(uint vaobj, uint index); void GetVertexArrayIntegervEXT(uint vaobj, enum pname, int *param); void GetVertexArrayPointervEXT(uint vaobj, enum pname, void **param); void GetVertexArrayIntegeri_vEXT(uint vaobj, uint index, enum pname, int *param); void GetVertexArrayPointeri_vEXT(uint vaobj, uint index, enum pname, void **param); void *MapNamedBufferRangeEXT(uint buffer, intptr offset, sizeiptr length, bitfield access); void FlushMappedNamedBufferRangeEXT(uint buffer, intptr offset, sizeiptr length); New Tokens Accepted by the parameter of GetBooleanIndexedvEXT, GetIntegerIndexedvEXT, GetFloatIndexedvEXT, GetDoubleIndexedvEXT: GetBooleani_v, GetIntegeri_v, GetFloati_vEXT, GetDoublei_vEXT: PROGRAM_MATRIX_EXT 0x8E2D TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F Additions to Chapter 2 of the OpenGL 3.0 Specification (OpenGL Operation) Insert the following after the 2nd sentence in the 4th paragraph in Section 2.5 (Errors): "Certain commands and queries provide direct state access to named objects (such as TextureParameteriEXT, NamedProgramLocalParameter4dEXT, NamedRenderbufferStorageEXT, NamedFramebufferTexture2DEXT, GetTextureImageEXT, etc.) and perform implicit object initialization when provided unused object names. When these commands and queries are given an object name not currently used, these commands and queries will first (prior to any further error checking) make the name used and appropriately initialize the named object to a new object state vector. After this object initialization for unused names takes place, the command may subsequently generate an error. In this case, the command's state update or query's result is ignored, but the name still becomes used and the object initialization still takes place." Add after the paragraph describing EnableClientState in Section 2.8 (Vertex Arrays): "The following commands: void EnableClientStateIndexedEXT(enum array, uint index); void DisableClientStateIndexedEXT(enum array, uint index); void EnableClientStateiEXT(enum array, uint index); void DisableClientStateiEXT(enum array, uint index); are equivalent (assuming no errors) to the following: if (array == TEXTURE_COORD_ARRAY) { int savedClientActiveTexture; GetIntegerv(CLIENT_ACTIVE_TEXTURE, &savedClientActiveTexture); ClientActiveTexture(TEXTURE0+index); XXX(array); ClientActiveTexture(savedActiveTexture); } else { // Invalid enum } where index is the index parameter to the listed commands and XXX is the name of the command without its "Indexed" or "i" suffix (either EnableClientState or DisableClientState). The error INVALID_VALUE is generated if index is greater or equal to the implementation's NUM_TEXTURE_COORDS value. The error INVALID_ENUM is generated if array is not TEXTURE_COORD_ARRAY." Add before the last paragraph in Section 2.8 (Vertex Arrays): "The following command: void MultiTexCoordPointerEXT(enum texunit, int size, enum type, sizei stride, const void *pointer); is equivalent (assuming no errors) to the following: int savedClientActiveTexture; GetIntegerv(CLIENT_ACTIVE_TEXTURE, &savedClientActiveTexture); ClientActiveTexture(texunit); TexCoordPointer(...); ClientActiveTexture(savedActiveTexture); where ... is the list of the arguments for the command excluding the index parameter." Add to the end of section 2.9 (Buffer Objects), before section 2.9.1 (Vertex Arrays in Buffer Objects): "The following commands: void NamedBufferDataEXT(uint buffer, sizeiptr size, const void *data, enum usage); void NamedBufferSubDataEXT(uint buffer, intptr offset, sizeiptr size, const void *data); void* MapNamedBufferEXT(uint buffer, enum access); boolean UnmapNamedBufferEXT(uint buffer); void *MapNamedBufferRangeEXT(uint buffer, intptr offset, sizeiptr length, bitfield access); void FlushMappedNamedBufferRangeEXT(uint buffer, intptr offset, sizeiptr length); void NamedCopyBufferSubDataEXT(uint readBuffer, uint writeBuffer, intptr readOffset, intptr writeOffset, sizeiptr size); operate identically to the corresponding command where "Named" is deleted from the name (and extension suffixes are dropped or updated appropriately) except, rather than updating the currently bound buffer for the buffer target parameter (a parameter not present for these listed commands), these "Named" commands update the buffer object named by the initial buffer parameter. The remaining parameters following the initial buffer parameter for the listed "Named" commands match the parameters for the corresponding non-"Named" buffer command (except the target parameter is not needed because the buffer object to update is identified by its name) and are interpreted as they are for the non-"Named" buffer command. If the buffer object named by the buffer parameter has not been previously bound or has been deleted since the last binding, the GL first creates a new state vector, initialized with a zero-sized memory buffer and comprising the state values listed in table 2.6. There is no buffer corresponding to the name zero, these commands generate the INVALID_OPERATION error if the buffer parameter is zero." Add to the end of Section 2.10 (Vertex Array Objects): "The following commands: void VertexArrayVertexOffsetEXT(uint vaobj, uint buffer, int size, enum type, sizei stride, intptr offset); void VertexArrayColorOffsetEXT(uint vaobj, uint buffer, int size, enum type, sizei stride, intptr offset); void VertexArrayEdgeFlagOffsetEXT(uint vaobj, uint buffer, sizei stride, intptr offset); void VertexArrayIndexOffsetEXT(uint vaobj, uint buffer, enum type, sizei stride, intptr offset); void VertexArrayNormalOffsetEXT(uint vaobj, uint buffer, enum type, sizei stride, intptr offset); void VertexArrayTexCoordOffsetEXT(uint vaobj, uint buffer, int size, enum type, sizei stride, intptr offset); void VertexArrayMultiTexCoordOffsetEXT(uint vaobj, uint buffer, enum texunit, int size, enum type, sizei stride, intptr offset); void VertexArrayFogCoordOffsetEXT(uint vaobj, uint buffer, enum type, sizei stride, intptr offset); void VertexArraySecondaryColorOffsetEXT(uint vaobj, uint buffer, int size, enum type, sizei stride, intptr offset); void VertexArrayVertexAttribOffsetEXT(uint vaobj, uint buffer, uint index, int size, enum type, boolean normalized, sizei stride, intptr offset); void VertexArrayVertexAttribIOffsetEXT(uint vaobj, uint buffer, uint index, int size, enum type, sizei stride, intptr offset); operate identically to the corresponding command where "VertexArray" is deleted from the name and "Offset" is changed to "Pointer" (and extension suffixes are dropped or updated appropriately) except, 1) rather than updating the currently in use vertex array object, these "VertexArray" commands update the vertex array object named by the initial vaobj parameter, and 2) the corresponding command operates as if the ARRAY_BUFFER buffer binding is bound to the buffer named by the buffer parameter. The remaining parameters following the initial vaobj parameter for the listed "VertexArray" commands match the parameters for the corresponding non-"VertexArray" vertex array specification command and are interpreted as they are for the non-"VertexArray" vertex array specification command. The one exception is that final intptr offset parameter of the "VertexArray" command is cast to the final pointer parameter of the non-"VertexArray" command (intptr is guaranteed to be large enough to store any pointer value). If the vertex array object named by the vaobj parameter has not been previously bound but has been generated (without subsequent deletion) by GenVertexArrays, the GL first creates a new state vector in the same manner as when BindVertexArray creates a new vertex array object. However these commands fail and an INVALID_OPERATION error is generated if vaobj is not a name returned from a previous call to GenVertexArrays, or if such a name has since been deleted with DeleteVertexArrays. If the buffer object named by the buffer parameter is non-zero and has not been previously bound or has been deleted since the last binding, the GL first creates a new state vector, initialized with a zero-sized memory buffer and comprising the state values listed in table 2.6. If the buffer object named by the buffer parameter is zero, these commands update the vertex array client-state. If the buffer object named by the buffer parameter is non-zero and the offset parameter is negative, generate the INVALID_VALUE error. No error is generated in the case where buffer is zero because the offset might be valid pointer than just happens to be negative when cast to a intptr type. The following commands: void EnableVertexArrayEXT(uint vaobj, enum array); void DisableVertexArrayEXT(uint vaobj, enum array); void EnableVertexArrayAttribEXT(uint vaobj, uint index); void DisableVertexArrayAttribEXT(uint vaobj, uint index); operate identically to EnableClientState, DisableClientState, EnableVertexAttribArray, and DisableVertexAttribArray respectively except rather than updating the current vertex array client-state these "VertexArray" commands update the vertex array enables within the vertex array object named by the initial vaobj parameter. The array parameter matches the array parameter for the corresponding EnableClientState and DisableClientState commands. The index parameter matches the index parameter for the corresponding EnableVertexAttribArray and DisableVertexAttribArray commands. Additionally EnableVertexArrayEXT and DisableVertexArrayEXT accept the tokens TEXTURE0 through TEXTUREn where n is less than the implementation-dependent limit of MAX_TEXTURE_COORDS. For these GL_TEXTUREi tokens, EnableVertexArrayEXT and DisableVertexArrayEXT act identically to EnableVertexArrayEXT(vaobj, TEXTURE_COORD_ARRAY) or DisableVertexArrayEXT(vaobj, TEXTURE_COORD_ARRAY) respectively as if the active client texture is set to texture coordinate set i based on the token TEXTUREi indicated by array. If the vertex array object named by the vaobj parameter has not been previously bound but has been generated (without subsequent deletion) by GenVertexArrays, the GL first creates a new state vector in the same manner as when BindVertexArray creates a new vertex array object. However these commands fail and an INVALID_OPERATION error is generated if vaobj is not a name returned from a previous call to GenVertexArrays, or if such a name has since been deleted with DeleteVertexArrays." Add to the end of Section 2.12.2 (Matrices): "The following commands: void MatrixLoadfEXT(enum matrixMode, const float *m); void MatrixLoaddEXT(enum matrixMode, const double *m); void MatrixLoadTransposefEXT(enum matrixMode, const float *m); void MatrixLoadTransposedEXT(enum matrixMode, const double *m); void MatrixMultfEXT(enum matrixMode, const float *m); void MatrixMultdEXT(enum matrixMode, const double *m); void MatrixMultTransposefEXT(enum matrixMode, const float *m); void MatrixMultTransposedEXT(enum matrixMode, const double *m); void MatrixLoadIdentityEXT(enum matrixMode); void MatrixRotatefEXT(enum matrixMode, float angle, float x, float y, float z); void MatrixRotatedEXT(enum matrixMode, double angle, double x, double y, double z); void MatrixScalefEXT(enum matrixMode, float x, float y, float z); void MatrixScaledEXT(enum matrixMode, double x, double y, double z); void MatrixTranslatefEXT(enum matrixMode, float x, float y, float z); void MatrixTranslatedEXT(enum matrixMode, double x, double y, double z); void MatrixOrthoEXT(enum matrixMode, double l, double r, double b, double t, double n, double f); void MatrixFrustumEXT(enum matrixMode, double l, double r, double b, double t, double n, double f); void MatrixPushEXT(enum matrixMode); void MatrixPopEXT(enum matrixMode); are equivalent (assuming no errors) to the following: int savedMatrixMode; GetIntegerv(MATRIX_MODE, &savedMatrixMode); if (matrixMode >= TEXTURE0 && matrixMode <= TEXTURE31) { int savedActiveTexture; MatrixMode(TEXTURE); GetIntegerv(ACTIVE_TEXTURE, &savedActiveTexture); ActiveTexture(matrixMode); XXX(...); ActiveTexture(savedActiveTexture); } else { MatrixMode(matrixMode); XXX(...); } MatrixMode(savedMatrixMode); where matrixMode is the matrixMode parameter to the listed commands, XXX is found in Table 2.selectorFreeMatrixCommands, and ... is the list of the remaining arguments for the command that follow the initial matrixMode parameter. Table 2.selectorFreeMatrixCommands: Selector-free Command Name XXX -------------------------- -------------------- MatrixLoadfEXT LoadMatrixf MatrixLoaddEXT LoadMatrixd MatrixLoadTransposefEXT LoadTransposeMatrixf MatrixLoadTransposedEXT LoadTransposeMatrixd MatrixMultfEXT MultMatrixf MatrixMultdEXT MultMatrixd MatrixMultTransposefEXT MultTransposeMatrixf MatrixMultTransposedEXT MultTransposeMatrixd MatrixLoadIdentityEXT LoadIdentity MatrixRotatefEXT Rotatef MatrixRotatedEXT Rotated MatrixScalefEXT Scalef MatrixScaledEXT Scaled MatrixTranslatefEXT Translatef MatrixTranslatedEXT Translated MatrixOrthoEXT Ortho MatrixFrustumEXT Frustum MatrixPushEXT PushMatrix MatrixPopEXT PopMatrix" Add to the end of Section 2.20.3 (Shader Variables): "Program-specific Uniform Updates The following commands: void ProgramUniform1fEXT(uint program, int location, float v0); void ProgramUniform2fEXT(uint program, int location, float v0, float v1); void ProgramUniform3fEXT(uint program, int location, float v0, float v1, float v2); void ProgramUniform4fEXT(uint program, int location, float v0, float v1, float v2, float v3); void ProgramUniform1iEXT(uint program, int location, int v0); void ProgramUniform2iEXT(uint program, int location, int v0, int v1); void ProgramUniform3iEXT(uint program, int location, int v0, int v1, int v2); void ProgramUniform4iEXT(uint program, int location, int v0, int v1, int v2, int v3); void ProgramUniform1fvEXT(uint program, int location, sizei count, const float *value); void ProgramUniform2fvEXT(uint program, int location, sizei count, const float *value); void ProgramUniform3fvEXT(uint program, int location, sizei count, const float *value); void ProgramUniform4fvEXT(uint program, int location, sizei count, const float *value); void ProgramUniform1ivEXT(uint program, int location, sizei count, const int *value); void ProgramUniform2ivEXT(uint program, int location, sizei count, const int *value); void ProgramUniform3ivEXT(uint program, int location, sizei count, const int *value); void ProgramUniform4ivEXT(uint program, int location, sizei count, const int *value); void ProgramUniformMatrix2fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniformMatrix3fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniformMatrix4fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniformMatrix2x3fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniformMatrix3x2fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniformMatrix2x4fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniformMatrix4x2fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniformMatrix3x4fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniformMatrix4x3fvEXT(uint program, int location, sizei count, boolean transpose, const float *value); void ProgramUniform1uiEXT(uint program, int location, uint v0); void ProgramUniform2uiEXT(uint program, int location, uint v0, uint v1); void ProgramUniform3uiEXT(uint program, int location, uint v0, uint v1, uint v2); void ProgramUniform4uiEXT(uint program, int location, uint v0, uint v1, uint v2, uint v3); void ProgramUniform1uivEXT(uint program, int location, sizei count, const uint *value); void ProgramUniform2uivEXT(uint program, int location, sizei count, const uint *value); void ProgramUniform3uivEXT(uint program, int location, sizei count, const uint *value); void ProgramUniform4uivEXT(uint program, int location, sizei count, const uint *value); operate identically to the corresponding command where "Program" is deleted from the name (and extension suffixes are dropped or updated appropriately) except, rather than updating the currently in use program object, these "Program" commands update the program object named by the initial program parameter. The remaining parameters following the initial program parameter for the listed "Program" commands match the parameters for the corresponding non-"Program" uniform command and are interpreted as they are for the non-"Program" uniform command. If the program named by the program parameter is not created or has not been successfully linked, the error INVALID_OPERATION is generated." Additions to Chapter 3 of the OpenGL 3.0 Specification (Rasterization) Add to the end of section 3.8.12 (Texture Objects): "Texture Object State Update The command void BindMultiTextureEXT(enum texunit, enum target, uint texture); operates identically to BindTexture except, rather than binding the named texture object to the current active texture's target binding specified by the target parameter, BindMultiTextureEXT binds the named texture to the specified target binding of texunit. These texture object state update commands: void TextureParameteriEXT(uint texture, enum target, enum pname, int param); void TextureParameterivEXT(uint texture, enum target, enum pname, const int *param); void TextureParameterfEXT(uint texture, enum target, enum pname, float param); void TextureParameterfvEXT(uint texture, enum target, enum pname, const float *param); void TextureParameterIivEXT(uint texture, enum target, enum pname, const int *params); void TextureParameterIuivEXT(uint texture, enum target, enum pname, const uint *params); void TextureImage1DEXT(uint texture, enum target, int level, int internalformat, sizei width, int border, enum format, enum type, const void *pixels); void TextureImage2DEXT(uint texture, enum target, int level, int internalformat, sizei width, sizei height, int border, enum format, enum type, const void *pixels); void TextureSubImage1DEXT(uint texture, enum target, int level, int xoffset, sizei width, enum format, enum type, const void *pixels); void TextureSubImage2DEXT(uint texture, enum target, int level, int xoffset, int yoffset, sizei width, sizei height, enum format, enum type, const void *pixels); void CopyTextureImage1DEXT(uint texture, enum target, int level, enum internalformat, int x, int y, sizei width, int border); void CopyTextureImage2DEXT(uint texture, enum target, int level, enum internalformat, int x, int y, sizei width, sizei height, int border); void CopyTextureSubImage1DEXT(uint texture, enum target, int level, int xoffset, int x, int y, sizei width); void CopyTextureSubImage2DEXT(uint texture, enum target, int level, int xoffset, int yoffset, int x, int y, sizei width, sizei height); void TextureImage3DEXT(uint texture, enum target, int level, int internalformat, sizei width, sizei height, sizei depth, int border, enum format, enum type, const void *pixels); void TextureSubImage3DEXT(uint texture, enum target, int level, int xoffset, int yoffset, int zoffset, sizei width, sizei height, sizei depth, enum format, enum type, const void *pixels); void CopyTextureSubImage3DEXT(uint texture, enum target, int level, int xoffset, int yoffset, int zoffset, int x, int y, sizei width, sizei height); void TextureBufferEXT(uint texture, enum target, enum internalformat, uint buffer); void CompressedTextureImage3DEXT(uint texture, enum target, int level, enum internalformat, sizei width, sizei height, sizei depth, int border, sizei imageSize, const void *data); void CompressedTextureImage2DEXT(uint texture, enum target, int level, enum internalformat, sizei width, sizei height, int border, sizei imageSize, const void *data); void CompressedTextureImage1DEXT(uint texture, enum target, int level, enum internalformat, sizei width, int border, sizei imageSize, const void *data); void CompressedTextureSubImage3DEXT(uint texture, enum target, int level, int xoffset, int yoffset, int zoffset, sizei width, sizei height, sizei depth, enum format, sizei imageSize, const void *data); void CompressedTextureSubImage2DEXT(uint texture, enum target, int level, int xoffset, int yoffset, sizei width, sizei height, enum format, sizei imageSize, const void *data); void CompressedTextureSubImage1DEXT(uint texture, enum target, int level, int xoffset, sizei width, enum format, sizei imageSize, const void *data); void CompressedTextureImage3DEXT(uint texture, enum target, int level, enum internalformat, sizei width, sizei height, sizei depth, int border, sizei imageSize, const void *data); void TextureBufferEXT(uint texture, enum target, enum internalformat, uint buffer); void TextureRenderbufferEXT(uint texture, enum target, uint renderbuffer); operate identically to the corresponding command where "Texture" is substituted for "Tex" (and extension suffixes are dropped or updated appropriately) except, rather than updating the current bound texture for the texture unit indicated by the current active texture state and the target parameter, these "Texture" commands update the texture object named by the initial texture parameter. If the texture parameter is zero, then the target parameter selects the default texture of the specified target to update. The remaining parameters following the initial texture parameter for the listed "Texture" commands match the parameters for the corresponding "Tex" command and are interpreted as they are for the "Tex" command. If the texture parameter is for an unused name, the name becomes used and the named texture object is set to a new state vector, comprising all the state values listed in section 3.8.11, set to the same initial values prior to the command's state update. If the texture parameter is for a used name and that named texture object has a different target than the specified target parameter, the INVALID_OPERATION error is generated. One consequence of this error for commands that accepts TEXTURE_PROXY_* as a valid target parameter is TEXTURE_PROXY_* target tokens generate errors if used with a non-zero texture parameter because the target of a non-default (non-zero) texture object is never a proxy target." Add before the last paragraph of Section 3.8.16 (Texture Application): "The following commands (introduced by EXT_draw_buffers2): void EnableIndexedEXT(enum cap, uint index); void Enablei(enum cap, uint index); void DisableIndexedEXT(enum cap, uint index); void Disablei(enum cap, uint index); are equivalent (assuming no errors) to the following: int savedActiveTexture; GetIntegerv(ACTIVE_TEXTURE, &savedActiveTexture); ActiveTexture(TEXTURE0+index); XXX(cap); ActiveTexture(savedActiveTexture); where index is the index parameter to the listed commands and XXX is the name of the command without its "Indexed" or "i" suffix (either Enable or Disable) when the cap parameter is one of the texture-related enable token depending on the active texture state, namely TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_CUBE_MAP, TEXTURE_RECTANGLE_ARB, TEXTURE_GEN_S, TEXTURE_GEN_T, TEXTURE_GEN_R, or TEXTURE_GEN_Q." Add NEW section 3.8.X (Multitexture Commands): after section 3.8.16 (Texture Application): "These multitexture commands: void MultiTexCoordPointerEXT(enum texunit, int size, enum type, sizei stride, const void *pointer); void MultiTexEnvfEXT(enum texunit, enum target, enum pname, float param); void MultiTexEnvfvEXT(enum texunit, enum target, enum pname, const float *params); void MultiTexEnviEXT(enum texunit, enum target, enum pname, int param); void MultiTexEnvivEXT(enum texunit, enum target, enum pname, const int *params); void MultiTexGendEXT(enum texunit, enum coord, enum pname, double param); void MultiTexGendvEXT(enum texunit, enum coord, enum pname, const double *params); void MultiTexGenfEXT(enum texunit, enum coord, enum pname, float param); void MultiTexGenfvEXT(enum texunit, enum coord, enum pname, const float *params); void MultiTexGeniEXT(enum texunit, enum coord, enum pname, int param); void MultiTexGenivEXT(enum texunit, enum coord, enum pname, const int *params); void MultiTexParameteriEXT(enum texunit, enum target, enum pname, int param); void MultiTexParameterivEXT(enum texunit, enum target, enum pname, const int *param); void MultiTexParameterfEXT(enum texunit, enum target, enum pname, float param); void MultiTexParameterfvEXT(enum texunit, enum target, enum pname, const float *param); void MultiTexParameterIivEXT(enum texunit, enum target, enum pname, const int *params); void MultiTexParameterIuivEXT(enum texunit, enum target, enum pname, const uint *params); void MultiTexImage1DEXT(enum texunit, enum target, int level, int internalformat, sizei width, int border, enum format, enum type, const void *pixels); void MultiTexImage2DEXT(enum texunit, enum target, int level, int internalformat, sizei width, sizei height, int border, enum format, enum type, const void *pixels); void MultiTexSubImage1DEXT(enum texunit, enum target, int level, int xoffset, sizei width, enum format, enum type, const void *pixels); void MultiTexSubImage2DEXT(enum texunit, enum target, int level, int xoffset, int yoffset, sizei width, sizei height, enum format, enum type, const void *pixels); void CopyMultiTexImage1DEXT(enum texunit, enum target, int level, enum internalformat, int x, int y, sizei width, int border); void CopyMultiTexImage2DEXT(enum texunit, enum target, int level, enum internalformat, int x, int y, sizei width, sizei height, int border); void CopyMultiTexSubImage1DEXT(enum texunit, enum target, int level, int xoffset, int x, int y, sizei width); void CopyMultiTexSubImage2DEXT(enum texunit, enum target, int level, int xoffset, int yoffset, int x, int y, sizei width, sizei height); void MultiTexImage3DEXT(enum texunit, enum target, int level, int internalformat, sizei width, sizei height, sizei depth, int border, enum format, enum type, const void *pixels); void MultiTexSubImage3DEXT(enum texunit, enum target, int level, int xoffset, int yoffset, int zoffset, sizei width, sizei height, sizei depth, enum format, enum type, const void *pixels); void CopyMultiTexSubImage3DEXT(enum texunit, enum target, int level, int xoffset, int yoffset, int zoffset, int x, int y, sizei width, sizei height); void CompressedMultiTexImage3DEXT(enum texunit, enum target, int level, enum internalformat, sizei width, sizei height, sizei depth, int border, sizei imageSize, const void *data); void CompressedMultiTexImage2DEXT(enum texunit, enum target, int level, enum internalformat, sizei width, sizei height, int border, sizei imageSize, const void *data); void CompressedMultiTexImage1DEXT(enum texunit, enum target, int level, enum internalformat, sizei width, int border, sizei imageSize, const void *data); void CompressedMultiTexSubImage3DEXT(enum texunit, enum target, int level, int xoffset, int yoffset, int zoffset, sizei width, sizei height, sizei depth, enum format, sizei imageSize, const void *data); void CompressedMultiTexSubImage2DEXT(enum texunit, enum target, int level, int xoffset, int yoffset, sizei width, sizei height, enum format, sizei imageSize, const void *data); void CompressedMultiTexSubImage1DEXT(enum texunit, enum target, int level, int xoffset, sizei width, enum format, sizei imageSize, const void *data); void MultiTexBufferEXT(enum texunit, enum target, enum internalformat, uint buffer); void MultiTexRenderbufferEXT(enum texunit, enum target, uint renderbuffer); are equivalent (assuming no errors) to the following: int savedActiveTexture; GetIntegerv(ACTIVE_TEXTURE, &savedActiveTexture); ActiveTexture(texunit); XXX(...); ActiveTexture(savedActiveTexture); where XXX is the name of the command without its "Multi" prefix (and extension suffixes are dropped or updated appropriately) and ... is the list of the arguments for the command excluding the index parameter." Additions to Chapter 4 of the OpenGL 3.0 Specification (Per-Fragment Operations and the Frame Buffer) Add new section 4.4.7 (Named Access): "The following commands: void NamedRenderbufferStorageEXT(uint renderbuffer, enum internalformat, sizei width, sizei height); void NamedRenderbufferStorageMultisampleEXT(uint renderbuffer, sizei samples, enum internalformat, sizei width, sizei height); void NamedRenderbufferStorageMultisampleCoverageEXT(uint renderbuffer, sizei coverageSamples, sizei colorSamples, enum internalformat, sizei width, sizei height); operate identically to the corresponding command where "Named" is deleted from the name (and extension suffixes are dropped or updated appropriately) except, rather than updating the currently bound renderbuffer for the renderbuffer target parameter (a parameter not present for these listed commands), these "Named" commands update the renderbuffer object named by the initial renderbuffer parameter. The remaining parameters following the initial renderbuffer parameter for the listed "Named" commands match the parameters for the corresponding non-"Named" renderbuffer command and are interpreted as they are for the non-"Named" renderbuffer command; and the target parameter is assumed to be RENDERBUFFER. If the renderbuffer object named by the renderbuffer parameter has not been previously bound or has been deleted since the last binding, the GL first creates a new state vector in the same manner as when BindRenderbuffer creates a new renderbuffer object. The following commands (and query): void NamedFramebufferTexture1DEXT(uint framebuffer, enum attachment, enum textarget, uint texture, int level); void NamedFramebufferTexture2DEXT(uint framebuffer, enum attachment, enum textarget, uint texture, int level); void NamedFramebufferTexture3DEXT(uint framebuffer, enum attachment, enum textarget, uint texture, int level, int zoffset); void NamedFramebufferRenderbufferEXT(uint framebuffer, enum attachment, enum renderbuffertarget, uint renderbuffer); void NamedFramebufferTextureEXT(uint framebuffer, enum attachment, uint texture, int level); void NamedFramebufferTextureLayerEXT(uint framebuffer, enum attachment, uint texture, int level, int layer); void NamedFramebufferTextureFaceEXT(uint framebuffer, enum attachment, uint texture, int level, enum face); void GetNamedFramebufferAttachmentParameterivEXT(uint framebuffer, enum attachment, enum pname, int *params); operate identically to the corresponding command (or query) where "Named" is deleted from the name (and extension suffixes are dropped or updated appropriately) except, rather than updating the currently bound framebuffer for the framebuffer target parameter (a parameter not present for these listed commands and query), these "Named" commands update (or the query queries) the framebuffer object named by the initial framebuffer parameter. The remaining parameters following the initial framebuffer parameter for the listed "Named" commands (or query) match the parameters for the corresponding non-"Named" framebuffer command (or query) and are interpreted as they are for the non-"Named" framebuffer command (or query); and the target parameter is assumed to be FRAMEBUFFER. If the framebuffer object named by the framebuffer parameter has not been previously bound or has been deleted since the last binding, the GL first creates a new state vector in the same manner as when BindFramebuffer creates a new framebuffer object. The commands void FramebufferDrawBufferEXT(uint framebuffer, enum mode); void FramebufferDrawBuffersEXT(uint framebuffer, sizei n, const enum *bufs) void FramebufferReadBufferEXT(uint framebuffer, enum mode); operate identically to DrawBuffer, DrawBuffers, and ReadBuffer (without the initial framebuffer parameter) respectively except rather than updating the draw buffers or read buffer of the currently bound framebuffer object or the default window-system-provided framebuffer (i.e., FRAMEBUFFER_BINDING is zero), these commands update the draw buffers or read buffer of the framebuffer object named by the framebuffer parameter. When the framebuffer parameter is zero, the default window-system provided framebuffer is updated (even if the window-system-provided framebuffer is not currently bound). If the framebuffer object named by the framebuffer parameter has not been previously bound or has been deleted since the last binding, the GL first creates a new state vector in the same manner as when BindFramebuffer creates a new framebuffer object. The query void GetFramebufferParameterivEXT(uint framebuffer, enum pname, int *param); returns the framebuffer state of the framebuffer object specified by the framebuffer parameter. The pname parameter must be one of framebuffer dependent values listed in either table 4.nnn (namely DRAW_BUFFER, READ_BUFFER, or DRAW_BUFFER0 through DRAW_BUFFER15). The query returns the same value in param that GetIntegerv would return if called with pname and param as if the framebuffer specified by the framebuffer parameter had been bound with BindFramebuffer. If the framebuffer object named by the framebuffer parameter has not been previously bound or has been deleted since the last binding, the GL first creates a new state vector in the same manner as when BindFramebuffer creates a new framebuffer object. The command enum CheckNamedFramebufferStatusEXT(uint framebuffer, enum target); operates identically to CheckFramebufferStatus except rather than checking the currently bound framebuffer for the framebuffer target parameter, the status of the named framebuffer is checked where the target parameter indicates how the framebuffer would be bound. Because FRAMEBUFFER_UNSUPPORTED can be returned by CheckFramebufferStatus due to an implementation-dependent set of restrictions that might not be known until the framebuffer object is bound with BindFramebuffer, CheckNamedFramebufferStatusARB may in rare circumstances (ideally never) return FRAMEBUFFER_COMPLETE when CheckFramebufferStatus with the same framebuffer object bound would return FRAMEBUFFER_UNSUPPORTED. The framebuffer is checked for drawing if target is FRAMEBUFFER or DRAW_FRAMEBUFFER, and checked for reading if the target is READ_FRAMEBUFFER. If the framebuffer object named by the framebuffer parameter has not been previously bound or has been deleted since the last binding, the GL first creates a new state vector in the same manner as when BindFramebuffer creates a new framebuffer object. The commands void GenerateTextureMipmapEXT(uint texture, enum target); void GenerateMultiTexMipmapEXT(enum texunit, enum target); operate identically to GenerateMipmap except they use the texture specified by the named texture or specified texture unit respectively. The target parameter must be a token accepted by GenerateMipmap. If GenerateTextureMipmapARB's texture parameter is for an unused name, the name becomes used and the named texture object is set to a new state vector, comprising all the state values listed in section 3.8.11, set to the same initial values prior to the command's state update. If the texture parameter is for a used name and that named texture object has a different target than the specified target parameter, the INVALID_OPERATION error is generated." Additions to Chapter 5 of the OpenGL 3.0 Specification (Special Functions) In Section 5.4 (Display Lists): Add to list (page 310) of "Client state" commands "not compiled into the display list but are executed immediately": PushClientAttribDefaultEXT, ClientAttribDefaultEXT Add to list (page 310) of "Framebuffer and renderbuffer objects" commands "not compiled into the display list but are executed immediately": CheckNamedFramebufferStatusEXT, NamedRenderbufferStorageEXT, NamedFramebufferTexture1DEXT, NamedFramebufferTexture2DEXT, NamedFramebufferTexture3DEXT, NamedFramebufferRenderbufferEXT, GenerateTextureMipmapEXT, GenerateMultiTexMipmapEXT Add to the list (page 310) of "Vertex Buffer Objects" commands "not compiled into the display list but are executed immediately": NamedCopyBufferSubDataEXT Additions to Chapter 6 of the OpenGL 3.0 Specification (State and State Requests) Change section 6.1.1 (Simple Queries) so the second and third paragraphs read: "Indexed simple state variables are queried with the commands: void GetBooleani_v(enum target, uint index, boolean *data); void GetIntegeri_v(enum target, uint index, int *data); void GetFloati_vEXT(enum target, uint index, float *data); void GetDoublei_vEXT(enum target, uint index, double *data); void GetBooleanIndexedvEXT(enum target, uint index, boolean *data); void GetIntegerIndexedvEXT(enum target, uint index, int *data); void GetFloatIndexedvEXT(enum target, uint index, float *data); void GetDoubleIndexedvEXT(enum target, uint index, double *data); target is the name of the indexed state and index is the index of the particular element being queried. data is a pointer to a scalar or array of the indicated type in which to place the returned data. An INVALID_VALUE error is generated if index is outside the valide range for the indexed state target. Table 6.indexedGenericQueryCommands: Selector-free Command Name GetXXX -------------------------- -------------------- GetBooleanIndexedvEXT GetBooleanv GetIntegerIndexedvEXT GetIntegerv GetFloatIndexedvEXT GetFloatv GetDoubleIndexedvEXT GetDoublev GetBooleani_v GetBooleanv GetIntegeri_v GetIntegerv GetFloati_vEXT GetFloatv GetDoublei_vEXT GetDoublev When the target to one of these indexed queries is one of PROGRAM_MATRIX_EXT, TRANSPOSE_PROGRAM_MATRIX_EXT, or PROGRAM_MATRIX_STACK_DEPTH_EXT, the query operates indentically to (assuming no errors): int savedMatrixMode; GetIntegerv(MATRIX_MODE, &savedMatrixMode); MatrixMode(GL_MATRIX0_ARB+index); switch (target) { case PROGRAM_MATRIX_EXT: GetXXX(CURRENT_MATRIX_ARB, params); break; case TRANSPOSE_PROGRAM_MATRIX_EXT: GetXXX(TRANSPOSE_CURRENT_MATRIX_ARB, params); break; case PROGRAM_MATRIX_STACK_DEPTH_EXT: GetXXX(CURRENT_MATRIX_STACK_DEPTH_ARB, params); break; } MatrixMode(savedMatrixMode); where GetXXX is found in Table 6.indexedGenericQueryCommands. When the target to one of these indexed queries is one of CURRENT_MATRIX_NV, CURRENT_MATRIX_STACK_DEPTH_NV, CURRENT_RASTER_TEXTURE_COORDS, CURRENT_TEXTURE_COORDS, TEXTURE_BINDING_1D, TEXTURE_BINDING_1D_ARRAY, TEXTURE_BINDING_2D, TEXTURE_BINDING_2D_ARRAY, TEXTURE_BINDING_3D, TEXTURE_BINDING_BUFFER_EXT, TEXTURE_BINDING_CUBE_MAP, TEXTURE_BINDING_CUBE_MAP_ARRAY_NV, TEXTURE_BINDING_RECTANGLE_ARB, TEXTURE_BINDING_RENDERBUFFER_NV, TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV, TEXTURE_BUFFER_DATA_STORE_BINDING_EXT, TEXTURE_BUFFER_FORMAT_EXT, TEXTURE_GEN_Q, TEXTURE_GEN_R, TEXTURE_GEN_S, TEXTURE_GEN_T, TEXTURE_MATRIX, TEXTURE_STACK_DEPTH, TRANSPOSE_TEXTURE_MATRIX, GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP, or GL_TEXTURE_RECTANGLE_ARB, the query operates indentically (assuming no errors) to: int savedActiveTexture; GetIntegerv(ACTIVE_TEXTURE, &savedActiveTexture); ActiveTexture(TEXTURE0+index); GetXXX(target, params); ActiveTexture(savedActiveTexture); where GetXXX is found in Table 6.indexedGenericQueryCommands. When the target to one of these indexed queries is one of TEXTURE_COORD_ARRAY, TEXTURE_COORD_ARRAY_BUFFER_BINDING, TEXTURE_COORD_ARRAY_COUNT, TEXTURE_COORD_ARRAY_SIZE, TEXTURE_COORD_ARRAY_STRIDE, or TEXTURE_COORD_ARRAY_TYPE, the query operates indentically (assuming no errors) to: int savedClientActiveTexture; GetIntegerv(CLIENT_ACTIVE_TEXTURE, &savedClientActiveTexture); ClientActiveTexture(TEXTURE0+index); GetXXX(target, params); ClientActiveTexture(savedClientActiveTexture); where GetXXX is found in Table 6.indexedGenericQueryCommands. Finally, boolean IsEnabled(enum value); can be used to determine if value is currently enabled (as with Enable) or disabled and the queries boolean IsEnabledi(enum target, uint index); boolean IsEnabledIndexedEXT(enum cap, uint index); can be used to determine if the indexed state corresponding to target and index is enabled or disabled. An INVALID_VALUE error is generated if index is outside the valid range for the indexed state target. When the target to IsEnabledi or IsEnabledIndexedEXT is one of TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_CUBE_MAP, TEXTURE_RECTANGLE_ARB, TEXTURE_GEN_S, TEXTURE_GEN_T, TEXTURE_GEN_R, or TEXTURE_GEN_Q, the query operates indentically (assuming no errors) to: int savedActiveTexture; boolean rv; GetIntegerv(ACTIVE_TEXTURE, &savedActiveTexture); ActiveTexture(TEXTURE0+index); rv = IsEnabled(cap); ActiveTexture(savedActiveTexture); return rv; When the target to IsEnabledi or IsEnabledIndexedEXT is TEXTURE_COORD_ARRAY, the query operates indentically (assuming no errors) to: int savedClientActiveTexture; boolean rv; GetIntegerv(CLIENT_ACTIVE_TEXTURE, &savedClientActiveTexture); ClientActiveTexture(TEXTURE0+index); rv = IsEnabled(cap); ClientActiveTexture(savedClientActiveTexture); return rv;" Add new paragraph to the end of section 6.1.3 (Enumerated Queries): "These commands void GetTextureImageEXT(uint texture, enum target, int level, enum format, enum type, void *pixels); void GetTextureParameterfvEXT(uint texture, enum target, enum pname, float *params); void GetTextureParameterivEXT(uint texture, enum target, enum pname, int *params); void GetTextureLevelParameterfvEXT(uint texture, enum target, int level, enum pname, float *params); void GetTextureLevelParameterivEXT(uint texture, enum target, int level, enum pname, int *params); void GetTextureParameterIivEXT(uint texture, enum target, enum pname, int *params); void GetTextureParameterIuivEXT(uint texture, enum target, enum pname, uint *params); operate identically to the corresponding texture query command where "Texture" is substituted for "Tex" (and extension suffixes are dropped or updated appropriately) except, rather than querying the current bound texture for the texture unit indicated by the current active texture state and the target parameter, these "Texture" commands query the texture object named by the initial texture parameter. The remaining parameters following the initial texture parameter for the listed "Texture" commands match the parameters for the corresponding "Tex" command and are interpreted as they are for the "Tex" command." If the texture parameter is for an unused name, the name becomes used and the named texture object is set to a new state vector, comprising all the state values listed in section 3.8.11, set to the same initial values prior to the command's state query. If the texture parameter is for a used name and that named texture object has a different target than the specified target parameter, the INVALID_OPERATION error is generated. One consequence of this error for commands that accepts TEXTURE_PROXY_* as a valid target parameter (GetTextureLevelParameter*, but not GetTextureParameter*) is TEXTURE_PROXY_* target tokens generate errors if used with a non-zero texture parameter because the target of a non-default (non-zero) texture object is never a proxy target." Add new paragraph after the GetPointerv description in section 6.1.11 (Pointer and String Queries): "The following query void GetPointerIndexedvEXT(enum pname, uint index, void **params); is equivalent (assuming no errors) to the following: int savedClientActiveTexture; GetIntegerv(CLIENT_ACTIVE_TEXTURE, &savedClientActiveTexture); ClientActiveTexture(TEXTURE0+index); GetPointerv(pname, params); ClientActiveTexture(savedClientActiveTexture); where index is the index parameter to the listed queries and GetXXX is found in Table 6.indexedGenericQueryCommands. when the pname parameter is TEXTURE_COORD_ARRAY_POINTER." Add new paragraph to the end of section 6.1.13 (Buffer Object Queries): "These commands void GetNamedBufferParameterivEXT(uint buffer, enum pname, int *params); void GetNamedBufferPointervEXT(uint buffer, enum pname, void* *params); void GetNamedBufferSubDataEXT(uint buffer, intptr offset, sizeiptr size, void *data); operate identically to the corresponding command where "Named" is deleted from the name (and extension suffixes are dropped or updated appropriately) except, rather than querying the currently bound buffer for the buffer target parameter (a parameter not present for these listed commands), these "Named" commands query the buffer object named by the initial buffer parameter. The remaining parameters following the initial buffer parameter for the listed "Named" commands match the parameters for the corresponding non-"Named" buffer command (except the target parameter is not needed because the buffer object to query is identified by its name) and are interpreted as they are for the non-"Named" buffer command. If the buffer object named by the buffer parameter has not been previously bound or has been deleted since the last binding, the GL first creates a new state vector, initialized with a zero-sized memory buffer and comprising the state values listed in table 2.6. There is no buffer corresponding to the name zero, these commands generate the INVALID_OPERATION error if the buffer parameter is zero." Add new paragraph to the end of section after 6.1.14 (Vertex Array Object Queries): "The commands void GetVertexArrayIntegervEXT(uint vaobj, enum pname, int *param); void GetVertexArrayPointervEXT(uint vaobj, enum pname, void **param); void GetVertexArrayIntegeri_vEXT(uint vaobj, uint index, enum pname, int *param); void GetVertexArrayPointeri_vEXT(uint vaobj, uint index, enum pname, void **param); queries the parameters of the vertex array object named by vaobj. For GetVertexArrayIntegervEXT, pname must be one of the "Get value" tokens in tables 6.6, 6.7, 6.8, and 6.9 that use GetIntegerv, IsEnabled, or GetPointerv for their "Get command" (so excluding the VERTEX_ATTRIB_* tokens). For GetVertexArrayIntegeri_vEXT, pname must be one of the "Get value" tokens in tables 6.8 and 6.9 that use GetVertexAttribiv or GetVertexAttribPointerv (so allowing only the VERTEX_ATTRIB_* tokens) or a token of the form TEXTURE_COORD_ARRAY (the enable) or TEXTURE_COORD_ARRAY_*; index identifies the vertex attribute array to query or texture coordinate set index respectively. For GetVertexArrayPointervEXT, pname must be a *_ARRAY_POINTER token from tables 6.6, 6.7, and 6.8 excluding VERTEX_ATTRIB_ARRAY_POINTER. For GetVertexArrayPointeri_vEXT, pname must be VERTEX_ATTRIB_ARRAY_POINTER or TEXTURE_COORD_ARRAY_POINTER with the index parameter indicating the vertex attribute or texture coordindate set index. If the state queried by GetVertexArrayIntegervEXT or GetVertexArrayVertexAttribIntegervEXT is maintained as a pointer, the least significant bits of the pointer that fit within an int are returned in case a pointer is larger than an int. This behavior allows pointers treated as offsets (when less than 2^31) to be returned as integer values. If the vertex array object named by the vaobj parameter has not been previously bound but has been generated (without subsequent deletion) by GenVertexArrays, the GL first creates a new state vector in the same manner as when BindVertexArray creates a new vertex array object (hence the initial state will be returned). However these queries fail and an INVALID_OPERATION error is generated if vaobj is not a name returned from a previous call to GenVertexArrays, or if such a name has since been deleted with DeleteVertexArrays." Add NEW section after 6.1.15 (Shader and Program Queries): "16.1.X Multitexture Queries These queries void GetMultiTexEnvfvEXT(enum texunit, enum target, enum pname, float *params); void GetMultiTexEnvivEXT(enum texunit, enum target, enum pname, int *params); void GetMultiTexGendvEXT(enum texunit, enum coord, enum pname, double *params); void GetMultiTexGenfvEXT(enum texunit, enum coord, enum pname, float *params); void GetMultiTexGenivEXT(enum texunit, enum coord, enum pname, int *params); void GetMultiTexImageEXT(enum texunit, enum target, int level, enum format, enum type, void *pixels); void GetMultiTexParameterfvEXT(enum texunit, enum target, enum pname, float *params); void GetMultiTexParameterivEXT(enum texunit, enum target, enum pname, int *params); void GetMultiTexParameterIivEXT(enum texunit, enum target, enum pname, int *params); void GetMultiTexParameterIuivEXT(enum texunit, enum target, enum pname, uint *params); void GetMultiTexLevelParameterfvEXT(enum texunit, enum target, int level, enum pname, float *params); void GetMultiTexLevelParameterivEXT(enum texunit, enum target, int level, enum pname, int *params); void GetCompressedMultiTexImageEXT(enum texunit, enum target, int level, void *img); are equivalent (assuming no errors) to the following: int savedActiveTexture, savedClientActiveTexture; GetIntegerv(ACTIVE_TEXTURE, &savedActiveTexture); ActiveTexture(texunit); GetXXX(...); ActiveTexture(savedActiveTexture); where GetXXX is found in Table 6.MultiTexQueryCommands and ... is the list of the arguments for the command excluding the index parameter. Table 6.MultiTexQueryCommands: Selector-free Command Name GetXXX ------------------------------ -------------------- GetMultiTexEnvfvEXT GetTexEnvfv GetMultiTexEnvivEXT GetTexEnviv GetMultiTexGendvEXT GetTexGendv GetMultiTexGenfvEXT GetTexGenfv GetMultiTexGenivEXT GetTexGeniv GetMultiTexImageEXT GetTexImage GetMultiTexParameterfvEXT GetTexParameterfv GetMultiTexParameterivEXT GetTexParameteriv GetMultiTexParameterIivEXT GetTexParameterIiv GetMultiTexParameterIuivEXT GetTexParameterIuiv GetMultiTexLevelParameterivEXT GetTexLevelParameteriv GetMultiTexLevelParameterfvEXT GetTexLevelParameterfv GetCompressedMultiTexImageEXT GetCompressedTexImage Add new paragraphs after the first paragraph of section 6.1.15 (Saving and Restoring State): "The command void ClientAttribDefaultEXT(bitfield mask); resets portions of the client state, depending on the bits set in the mask parameter, to the initial values of the state. When CLIENT_PIXEL_STORE_BIT is set in mask, the pixel store state is set to the initial values documented in table 6.23. When CLIENT_VERTEX_ARRAY_BIT is set in mask, the client vertex array state is set to the initial values documented in table 6.6, 6.7, and 6.8. The command void PushClientAttribDefaultEXT(bitfield mask); is equivalent to: PushClientAttrib(mask); ClientAttribDefaultEXT(mask);" Additions to Appendix A of the OpenGL 3.0 Specification (Invariance) None. Interactions with the ARB_texture_rectangle specification If ARB_texture_rectangle (or NV_texture_rectangle or EXT_texture_rectangle) is NOT supported, ignore references to TEXTURE_RECTANGLE_ARB and GL_TEXTURE_BINDING_RECTANGLE_ARB in amended section 3.8.16 and new section 6.1.X. Interactions with the ARB_vertex_program specification If ARB_vertex_program is NOT supported, ignore the support for PROGRAM_MATRIX_EXT, TRANSPOSE_PROGRAM_MATRIX_EXT, and PROGRAM_MATRIX_STACK_DEPTH_EXT described for the GetBooleanIndexedvEXT, GetIntegerIndexedvEXT, GetFloatIndexedvEXT, and GetDoubleIndexedvEXT commands in section 6.1.X. Additions to the ARB_vertex_program specification Add to the end of section 2.14.1 (Program Objects): "This command void NamedProgramStringEXT(uint program, enum target, enum format, sizei len, const void *string); operates identically to ProgramStringARB except, rather than specifying the string for the currently bound program for the program target parameter, NamedProgramStringARB specifies the program string for the program object named by the initial program parameter. If the program parameter is for an unused program, the name becomes used and the named program object is set to a new program state vector as if BindProgramARB had been called on the unused program name with the given target parameter but without changing the target's program binding. If the program parameter is for a used name and that named program object has a different target than the specified target parameter, the INVALID_OPERATION error is generated. These commands void NamedProgramLocalParameter4dEXT(uint program, enum target, uint index, double x, double y, double z, double w); void NamedProgramLocalParameter4dvEXT(uint program, enum target, uint index, const double *params); void NamedProgramLocalParameter4fEXT(uint program, enum target, uint index, float x, float y, float z, float w); void NamedProgramLocalParameter4fvEXT(uint program, enum target, uint index, const float *params); operate identically to the corresponding command where "Named" is deleted from the name (and extension suffixes are updated to ARB appropriately) except, rather than updating the currently bound program for the program target parameter (a parameter not present for these listed commands), these "Named" commands update the program object named by the initial program parameter. If the program parameter is zero, then the target parameter selects the default program of the specified target to update. The remaining parameters following the initial program parameter for the listed "Named" commands match the parameters for the corresponding non-"Named" command and are interpreted as they are for the non-"Named" command. If the program parameter is for an unused name, the name becomes used and the named program object is assigned target-specific default values (see section 2.14.7 for vertex programs or section 3.11.8 for fragment programs), set to the same initial values prior to the command's state update. If the program parameter is for a used name and that named program object has a different target than the specified target parameter, the INVALID_OPERATION error is generated." Add to the end of section 6.1.12 (Program Queries): "These queries void GetNamedProgramLocalParameterdvEXT(uint program, enum target, uint index, double *params); void GetNamedProgramLocalParameterfvEXT(uint program, enum target, uint index, float *params); void GetNamedProgramivEXT(uint program, enum target, enum pname, int *params); void GetNamedProgramStringEXT(uint program, enum target, enum pname, void *string); operate identically to the corresponding query where "Named" is deleted from the name (and extension suffixes are updated to ARB appropriately) except, rather than querying the currently bound program for the program target parameter (a parameter not present for these listed query), these "Named" queries query the program object named by the initial program parameter. If the program parameter is zero, then the target parameter selects the default program of the specified target to query. The remaining parameters following the initial program parameter for the listed "Named" queries match the parameters for the corresponding non-"Named" query and are interpreted as they are for the non-"Named" query. If the program parameter is for an unused name, the name becomes used and the named program object is assigned target-specific default values (see section 2.14.7 for vertex programs or section 3.11.8 for fragment programs), set to the same initial values prior to the query's state query. If the program parameter is for a used name and that named program object has a different target than the specified target parameter, the INVALID_OPERATION error is generated." Additions to the EXT_gpu_program_parameters specification Add to the end of section 2.14.1 (Program Objects): "This command void NamedProgramLocalParameters4fvEXT(uint program, enum target, uint index, sizei count, const float *params); operate identically to ProgramLocalParameters4fvEXT except, rather than updating the currently bound program for the program target parameter (a parameter not present for these listed commands), these "Named" commands update the program object named by the initial program parameter. If the program parameter is zero, then the target parameter selects the default program of the specified target to update. The remaining parameters following the initial program parameter for the listed "Named" commands match the parameters for the corresponding non-"Named" command and are interpreted as they are for the non-"Named" command. If the program parameter is for an unused name, the name becomes used and the named program object is assigned target-specific default values (see section 2.14.7 for vertex programs or section 3.11.8 for fragment programs), set to the same initial values prior to the command's state update. If the program parameter is for a used name and that named program object has a different target than the specified target parameter, the INVALID_OPERATION error is generated." Additions to the NV_gpu_program4 specification Add to the end of section 2.14.1 (Program Objects): "These commands void NamedProgramLocalParameterI4iEXT(uint program, enum target, uint index, int x, int y, int z, int w); void NamedProgramLocalParameterI4ivEXT(uint program, enum target, uint index, const int *params); void NamedProgramLocalParametersI4ivEXT(uint program, enum target, uint index, sizei count, const int *params); void NamedProgramLocalParameterI4uiEXT(uint program, enum target, uint index, uint x, uint y, uint z, uint w); void NamedProgramLocalParameterI4uivEXT(uint program, enum target, uint index, const uint *params); void NamedProgramLocalParametersI4uivEXT(uint program, enum target, uint index, sizei count, const uint *params); operate identically to the corresponding command where "Named" is deleted from the name (and extension suffixes are updated to NV appropriately) except, rather than updating the currently bound program for the program target parameter (a parameter not present for these listed commands), these "Named" commands update the program object named by the initial program parameter. If the program parameter is zero, then the target parameter selects the default program of the specified target to update. The remaining parameters following the initial program parameter for the listed "Named" commands match the parameters for the corresponding non-"Named" command and are interpreted as they are for the non-"Named" command. If the program parameter is for an unused name, the name becomes used and the named program object is assigned target-specific default values (see section 2.14.7 for vertex programs or section 3.11.8 for fragment programs), set to the same initial values prior to the command's state update. If the program parameter is for a used name and that named program object has a different target than the specified target parameter, the INVALID_OPERATION error is generated." Add to the end of section 6.1.12 (Program Queries): "These queries void GetNamedProgramLocalParameterIivEXT(uint program, enum target, uint index, int *params); void GetNamedProgramLocalParameterIuivEXT(uint program, enum target, uint index, uint *params); operate identically to the corresponding query where "Named" is deleted from the name (and extension suffixes are updated to NV appropriately) except, rather than querying the currently bound program for the program target parameter (a parameter not present for these listed query), these "Named" queries query the program object named by the initial program parameter. If the program parameter is zero, then the target parameter selects the default program of the specified target to query. The remaining parameters following the initial program parameter for the listed "Named" queries match the parameters for the corresponding non-"Named" query and are interpreted as they are for the non-"Named" query. If the program parameter is for an unused name, the name becomes used and the named program object is assigned target-specific default values (see section 2.14.7 for vertex programs or section 3.11.8 for fragment programs), set to the same initial values prior to the query's state query. If the program parameter is for a used name and that named program object has a different target than the specified target parameter, the INVALID_OPERATION error is generated." Interactions with OpenGL 3.0 or the EXT_texture_integer specification If NEITHER OpenGL 3.0 nor EXT_texture_integer are supported, ignore the support for TextureParameterIivARB, TextureParameterIuivARB, GetTextureParameterIivARB, GetTextureParameterIuivARB, MultiTexParameterIivARB, MultiTexParameterIuivARB, GetMultiTexParameterIivARB, and GetMultiTexParameterIuivARB. Interactions with the EXT_texture_buffer_object specification If EXT_texture_buffer_object is NOT supported, ignore the support for TextureBufferARB and MultiTexBufferARB. Interactions with OpenGL 3.0 or the APPLE_vertex_array_object If NEITHER OpenGL 3.0 nor EXT_texture_integer are supported, ignore XXX If either OpenGL 3.0 or APPLE_vertex_array_object is supported, then ClientAttribDefaultARB also sets the VERTEX_ARRAY_BINDING vertex-array state to zero if the mask parameter has CLIENT_VERTEX_ARRAY_BIT set. This means PushClientAttribDefaultARB also sets the VERTEX_ARRAY_BINDING_APPLE vertex-array state to zero after pushing the client state. if the mask parameter has CLIENT_VERTEX_ARRAY_BIT set. Interactions with EXT_geometry_shader4 or NV_gpu_program4 If both EXT_geometry_shader4 and NV_gpu_program4 are NOT supported, ignore the support for NamedFramebufferTextureARB, NamedFramebufferTextureLayerARB, and NamedFramebufferTextureFaceARB. Interactions with OpenGL 3.0 or EXT_framebuffer_blit If NEITHER OpenGL 3.0 nor EXT_framebuffer_blit are supported, ignore the references to DRAW_FRAMEBUFFER and READ_FRAMEBUFFER in the discussion of CheckNamedFramebufferStatusARB and do not allow these tokens for the command's target parameter. Interactions with OpenGL 3.0 or EXT_framebuffer_multisample If NEITHER OpenGL 3.0 or EXT_framebuffer_multisample are supported, ignore the support for NamedRenderbufferStorageMultisampleARB. Interactions with NV_framebuffer_multisample_coverage If NV_framebuffer_multisample_coverage is NOT supported, ignore the support for NamedRenderbufferStorageMultisampleCoverageARB. Interactions with the NV_explicit_multisample specification If NV_explicit_multisample is NOT supported, ignore the support for TextureRenderbufferARB, MultiTexRenderbufferARB, TEXTURE_BINDING_RENDERBUFFER_NV, and TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV. Interactions with the NV_texture_cube_map_array specification If NV_texture_cube_map_array is NOT supported, ignore the support for TEXTURE_BINDING_CUBE_MAP_ARRAY_NV. Interactions with OpenGL 3.0 If OpenGL 3.0 is NOT supported, ignore the support for EnableClientStateiEXT, DisableClientStateiEXT, GetFloati_vEXT, GetDoublei_vEXT, GetPointeri_vEXT, VertexArrayVertexOffsetEXT, VertexArrayColorOffsetEXT, VertexArrayEdgeFlagOffsetEXT, VertexArrayIndexOffsetEXT, VertexArrayNormalOffsetEXT, VertexArrayTexCoordOffsetEXT, VertexArrayMultiTexCoordOffsetEXT, VertexArrayFogCoordOffsetEXT, VertexArraySecondaryColorOffsetEXT, VertexArrayVertexAttribOffsetEXT, VertexArrayVertexAttribIOffsetEXT, EnableVertexArrayEXT, DisableVertexArrayEXT, EnableVertexArrayAttribEXT, DisableVertexArrayAttribEXT, GetVertexArrayIntegervEXT, GetVertexArrayPointervEXT, GetVertexArrayVertexAttribParameterivEXT, GetVertexArrayVertexAttribPointervEXT, MapNamedBufferRangeEXT, and FlushMappedNamedBufferRangeEXT. If OpenGL 3.0 is NOT supported, ignore references to Enablei, Disablei, IsEnabledi, GetBooleani_v, and GetIntegeri_v. Additions to the AGL/GLX/WGL Specifications None. GLX Protocol XXX incomplete! ZZZZ values need to be registered! XXX ARB_vertex_program support is specified. The following rendering commands are sent to the server as part of a glXRender request: NamedProgramLocalParameter4fvEXT 2 36 rendering command length 2 ZZZZ rendering command opcode 4 ENUM program 4 ENUM target 4 CARD32 index 4 FLOAT32 params[0] 4 FLOAT32 params[1] 4 FLOAT32 params[2] 4 FLOAT32 params[3] NamedProgramLocalParameter4dvEXT 2 48 rendering command length 2 ZZZZ rendering command opcode 4 ENUM program 4 ENUM target 4 CARD32 index 8 FLOAT64 params[0] 8 FLOAT64 params[1] 8 FLOAT64 params[2] 8 FLOAT64 params[3] The NamedProgramStringEXT is potentially large, and hence can be sent in a glXRender or glXRenderLarge request. NamedProgramStringEXT 2 20+len+p rendering command length 2 ZZZZ rendering command opcode 4 ENUM program 4 ENUM target 4 ENUM format 4 sizei len len LISTofBYTE program p unused, p=pad(len) If the command is encoded in a glxRenderLarge request, the command opcode and command length fields above are expanded to 4 bytes each: 4 20+len+p rendering command length 4 ZZZZ rendering command opcode The remaining commands are non-rendering commands. These commands are sent separately (i.e., not as part of a glXRender or glXRenderLarge request), using the glXVendorPrivateWithReply request: GetNamedProgramLocalParameterfvEXT 1 CARD8 opcode (X assigned) 1 17 GLX opcode (glXVendorPrivateWithReply) 2 6 request length 4 ZZZZ vendor specific opcode 4 GLX_CONTEXT_TAG context tag 4 ENUM program 4 ENUM target 4 CARD32 index => 1 1 reply 1 unused 2 CARD16 sequence number 4 m reply length, m=(n==1?0:n) 4 unused 4 CARD32 n (number of parameter components) if (n=1) this follows: 4 FLOAT32 params 12 unused otherwise this follows: 16 unused n*4 LISTofFLOAT32 params GetNamedProgramLocalParameterdvEXT 1 CARD8 opcode (X assigned) 1 17 GLX opcode (glXVendorPrivateWithReply) 2 6 request length 4 ZZZZ vendor specific opcode 4 GLX_CONTEXT_TAG context tag 4 ENUM program 4 CARD32 index 4 ENUM target => 1 1 reply 1 unused 2 CARD16 sequence number 4 m reply length, m=(n==1?0:n*2) 4 unused 4 CARD32 n (number of parameter components) if (n=1) this follows: 8 FLOAT64 params 8 unused otherwise this follows: 16 unused n*8 LISTofFLOAT64 params GetNamedProgramivEXT 1 CARD8 opcode (X assigned) 1 17 GLX opcode (glXVendorPrivateWithReply) 2 6 request length 4 ZZZZ vendor specific opcode 4 GLX_CONTEXT_TAG context tag 4 ENUM program 4 ENUM target 4 ENUM pname => 1 1 reply 1 unused 2 CARD16 sequence number 4 m reply length, m=(n==1?0:n) 4 unused 4 CARD32 n if (n=1) this follows: 4 INT32 params 12 unused otherwise this follows: 16 unused n*4 LISTofINT32 params GetNamedProgramStringEXT 1 CARD8 opcode (X assigned) 1 17 GLX opcode (glXVendorPrivateWithReply) 2 6 request length 4 ZZZZ vendor specific opcode 4 GLX_CONTEXT_TAG context tag 4 ENUM program 4 ENUM target 4 ENUM pname => 1 1 reply 1 unused 2 CARD16 sequence number 4 (n+p)/4 reply length 4 unused 4 CARD32 n 16 unused n STRING program p unused, p=pad(n) Errors All the commands in this extension excepting ClientAttribDefaultEXT are expressed in terms of existing GL commands and the error that apply to those commands apply to the new commands. If an error occurs for any of the commands introduced by this extension, any selector used by the command is left undisturbed. Several errors are truly "new" with this extension: INVALID_OPERATION is generated by CopyTextureImage1DEXT, CopyTextureImage2DEXT, CopyTextureSubImage1DEXT, CopyTextureSubImage2DEXT, CopyTextureSubImage3DEXT, GetCompressedTextureImageEXT, GetTextureImageEXT, GetTextureLevelParameterfvEXT, GetTextureLevelParameterivEXT, GetTextureParameterfvEXT, GetTextureParameterIivEXT, GetTextureParameterIuivEXT, GetTextureParameterivEXT, TextureBufferEXT, TextureImage1DEXT, TextureImage2DEXT, TextureImage3DEXT, TextureParameterfEXT, TextureParameterfvEXT, TextureParameteriEXT, TextureParameterIivEXT, TextureParameterIuivEXT, TextureParameterivEXT, TextureSubImage1DEXT, TextureSubImage2DEXT, TextureSubImage3DEXT, and GenerateMultiTexMipmapEXT if the target parameter does not match the target type of the texture object named by the texture parameter. INVALID_OPERATION is generated by GetNamedBufferParameterivEXT, GetNamedBufferPointervEXT, GetNamedBufferSubDataEXT, MapNamedBufferEXT, NamedBufferDataEXT, NamedBufferSubDataEXT, and UnmapNamedBufferEXT if the buffer parameter is zero. INVALID_OPERATION is generated by ProgramUniform1fEXT, ProgramUniform2fEXT, ProgramUniform3fEXT, ProgramUniform4fEXT, ProgramUniform1iEXT, ProgramUniform2iEXT, ProgramUniform3iEXT, ProgramUniform4iEXT, ProgramUniform1fvEXT, ProgramUniform2fvEXT, ProgramUniform3fvEXT, ProgramUniform4fvEXT, ProgramUniform1ivEXT, ProgramUniform2ivEXT, ProgramUniform3ivEXT, ProgramUniform4ivEX, ProgramUniformMatrix2fvEXT, ProgramUniformMatrix3fvEXT, ProgramUniformMatrix4fvEXT, ProgramUniformMatrix2x3fv, ProgramUniformMatrix3x2fv, ProgramUniformMatrix2x4fv, ProgramUniformMatrix4x2fv, ProgramUniformMatrix3x4fv, ProgramUniformMatrix4x3fv, ProgramUniform1uiEXT, ProgramUniform2uiEXT, ProgramUniform3uiEXT, ProgramUniform4uiEXT, ProgramUniform1uivEXT, ProgramUniform2uivEXT, ProgramUniform3uivEXT, and ProgramUniform4uivEXT if the program named by the program parameter has not been successfully linked. INVALID_VALUE is generated by NamedProgramLocalParameter4dEXT, NamedProgramLocalParameter4dvEXT, NamedProgramLocalParameter4fEXT, NamedProgramLocalParameter4fvEXT, GetNamedProgramLocalParameterdvEXT, GetNamedProgramLocalParameterfvEXT, GetNamedProgramivEXT, and GetNamedProgramStringEXT if the program named by the program parameter does not exist. INVALID_OPERATION is generated by MultiTexCoordPointerEXT, VertexArrayMultiTexCoordOffsetEXT, MultiTexEnvfEXT, MultiTexEnvfvEXT, MultiTexEnviEXT, MultiTexEnvivEXT, MultiTexGendEXT, MultiTexGendvEXT, MultiTexGenfEXT, MultiTexGenfvEXT, MultiTexGeniEXT, MultiTexGenivEXT, MultiTexParameteriEXT, MultiTexParameterivEXT, MultiTexParameterfEXT, MultiTexParameterfvEXT, MultiTexParameterIivEXT, MultiTexParameterIuivEXT, MultiTexImage1DEXT, MultiTexImage2DEXT, MultiTexSubImage1DEXT, MultiTexSubImage2DEXT, CopyMultiTexImage1DEXT, CopyMultiTexImage2DEXT, CopyMultiTexSubImage1DEXT, CopyMultiTexSubImage2DEXT, MultiTexImage3DEXT, MultiTexSubImage3DEXT, CopyMultiTexSubImage3DEXT, MultiTexBufferEXT, GetMultiTexEnvfvEXT, GetMultiTexEnvivEXT, GetMultiTexGendvEXT, GetMultiTexGenfvEXT, GetMultiTexGenivEXT, GetMultiTexImageEXT, GetMultiTexParameterfvEXT, GetMultiTexParameterivEXT, GetMultiTexParameterIivEXT, GetMultiTexParameterIuivEXT, GetMultiTexLevelParameterivEXT, GetMultiTexLevelParameterfvEXT, and GetCompressedMultiTexImageEXT if the texunit parameter names a texture unit that is greater or equal in number to the implementations limit for maximum texture image units. INVALID_OPERATION is generated by FramebufferDrawBuffersEXT if a color buffer not currently allocated to the GL context is specified. INVALID_OPERATION is generated by FramebufferDrawBuffersEXT if is greater than the state MAX_DRAW_BUFFERS. INVALID_OPERATION is generated by FramebufferDrawBuffersEXT if value in does not correspond to one of the allowed buffers. INVALID_OPERATION is generated by FramebufferDrawBuffersEXT if a draw buffer other then NONE is specified more then once in . New State None. New Implementation Dependent State None. NVIDIA Implementation Details NVIDIA drivers prior to 330.00 (August 2013) have a bug where glMultiTexGeniEXT acts identically to glTexGeni (so glMultiTexGeniEXT ignores its texture unit parameter). As a workaround, use glMultiTexGenivEXT. So problematic code written as: glMultiTexGeniEXT(texUnit, coord, pname, value); can be rewritten as: GLenum pvalue = value; glMultiTexGenivEXT(texUnit, coord, pname, &pvalue); NVIDIA drivers prior to 330.00 (August 2013) do not support the glEnableVertexArrayEXT and glDisableVertexArrayEXT with the GL_TEXTUREi tokens and instead generate a GL_INVALID_ENUM error. See issue 32. The only workaround is to change the texture unit selector (glActiveTexture) and bind the vertex array object (glBindVertexArray) and call glEnable or glDisable with GL_TEXTURE_COORD_ARRAY. Alternatively use generic vertex attribute arrays instead of texture coordinate arrays. Issues (0) What is changed from version 1.0 to version 1.1 of this extension to support OpenGL 3.0? RESOLVED: Changes are primarily cosmetic except the addition of API for selector-free access to vertex array objects since that functionality is part of OpenGL 3.0: 1) Update all references to section numbering to OpenGL 3.0 section numbers. 2) Where EXT extensions have become part of OpenGL 3.0, refer to the functionality as part of OpenGL 3.0 rather than by extension name. 3) New selector-free API for vertex buffer objects since these were introduced by OpenGL 3.0. The EXT version specified a necessary glClientAttribDefaultEXT interaction with APPLE_vertex_buffer_object but didn't provide an selector-free API for vertex buffer objects. 4) Add new selector-free API for fine control over mapping buffer subranges into client space (glMapNamedBufferRangeEXT) and flushing modified data (glFlushMappedNamedBufferRangeEXT). 5) Add OpenGL 3.0-style aliases for the version 1.0 commands and queries that have "Indexed" in the name. OpenGL 3.0 has a convention where an "i" indexed indexed commands and queries. For example, glGetFloati_v and glGetFloatIndexedvEXT are identical queries. Likewise glEnableClientStateIndexedEXT and glEnableClientStateiEXT are identical commands. (1) What should this extension be called? RESOLVED: EXT_direct_state_access "direct" means state updates and queries are not indirected through a selector such as the matrix mode, active texture unit, active client texture unit, current texture binding, current vertex/fragment/geometry program, current GLSL program, or current buffer binding. "state" so there's not confusion about what this extension provides direct access to (not direct access to the hardware or the framebuffer, etc.). "access" is because this extension applies to both queries (reads) and updates (writes) of OpenGL state. Access is general enough to encompass both queries and updates. (2) Should we have a "direct_state_access" extension for each type of OpenGL state involved (matrix, program, GLSL, texture unit, texture object) or have one uber-extension? For example, EXT_direct_matrix_access, EXT_direct_texture_access, etc. RESOLVED: One uber-extension. This extension introduces no additional hardware functionality but rather provides commands to perform state updates and queries without having to change (and possibly query and restore) API selectors. The dependencies sections make it clear that if some functionality (say, GLSL) is not supported, implementations supporting this extension ignore the direct access API for the particular missing functionality. This simplifies the burden on applications to use the new direct access API. When this extension is supported, the application can assume all functionality supported by their respective extensions is available through the direct access commands introduced by this extension. (3) Explain the methodology for naming selector-free commands. The naming conventions seek to maximize consistency but differences between the various selectors and command subsets dictate differences in approach. The chosen naming conventions has two guiding principles: 1) making the selector-free commands similar to the existing selector-based commands in naming but also clearly and consistently distinguished (at least within each group of commands) from the existing selector-based commands to which selector-free commands correspond by a simple pattern, and 2) being conscious of the length in characters of the resulting command names. Selector-less matrix commands all start glMatrix* (rather than gl* or gl*Matrix[fd] for the corresponding selector-based commands). Rationale: The selector-based matrix commands have the classic verb-noun format (example: glLoadMatrixf) described in Kurt Akeley's "Syntax Rules for OpenGL Extensions" document (henceforth abbreviated SRfOE) while the selector-free versions have a noun-verb format. This variance from SRfOE conventions is deemed warranted for the sake of consistent naming of all the selector-free matrix commands. The alternative of using "NamedMatrix" as a suffix to the matrix commands was considered (example: glLoadNamedMatrixf rather than glLoadMatrixf) but most matrix commands do not contain the word Matrix so this leads to awkward constructions such as glFrustumNamedMatrix and glLoadIdentityNamedMatrix. glMatrixFrustum and glMatrixLoadIdentity were preferred despite the variance this creates with SRfOE. Also considered was adding "Named" or "NamedMatrix" as a prefix to the matrix commands (example: glNamedLoadMatrixf, glNamedFrustum, glNamedLoadIdentity; or glNamedMatrixLoadMatrixf, glNamedMatrixFrustum, glNamedMatrixLoadIdentity). But the "Named" prefix is awkward because it is not the frustum, etc. that is named but rather a matrix. The "NamedMatrix" prefix becomes awkward because of the length of the resulting commands while having a noun-verb format. The "Matrix" prefixed format (where "Matrix" appears in the command name only once) provides consistency of naming and minimizes command name length but at the consistency cost of varying with the SRfOE's verb-noun convention. Selector-less texture object commands all start glTexture* or glGetTexture* (rather than glTex* and glGetTex* for the corresponding selector-based commands). Rationale: SRfOE states "Tex" is an abbreviation for "Texture" in command names. However in the context of texture objects, the abbreviated "Texture" is used instead (example: glIsTexture, not glIsTex). The abbreviation "Tex" is used when texture is used as an adjective to describe state being specified (examples: glTexParameter* and glTexImage*). The unabbreviated "Texture" is used as a noun in command names. The selector-free texture object commands use the unabbreviated "Texture" as an adjective since a texture object is accessed directly where the "Tex" commands refer to texture state accessed indirectly based on the currently bound texture object. Selector-less multitexture texture unit commands and queries all replace "Tex" with "MultiTex" and a new initial texunit identifies the texture unit by token (mimicking how TexCoord2f is MultiTexCoord2f for multitexture immediate mode). Selector-less generic enables (glEnable, glDisable) for texture unit enables make use of the convention for indexed queries introduced by EXT_draw_buffers2 and also used by EXT_transform_feedback so use glEnableIndexedEXT and glDisableIndexedEXT. Selector-less generic queries (glGetIntegerv, glGetFloatv, glGetPointerv, etc) for texture unit state make use of the convention for indexed queries introduced by EXT_draw_buffers2 and also used by EXT_transform_feedback so use glGetIntegerIndexedvEXT, glGetFloatIndexedvEXT, glGetDoubleIndexedvEXT, glGetBooleanIndexedvEXT, and glIsEnabledIndexedEXT. OpenGL 3.0 introduced a new naming convention for indexed state enables and queries so glGetIntegeri_v, glGetFloati_vEXT, glGetDoublei_vEXT, and glGetBooleani_v, glIsEnabledi operate identically respectively to the prior indexed query list. Selector-less buffer object commands all start with glNamedBuffer or glGetNamedBuffer. Selector-less program parameter commands (for ARB_vertex_program-based extensions) all start glNamedProgram or glGetNamedProgram. Selector-less uniform commands for GLSL all start glProgramUniform. Selector-less framebuffer object commands all start with glNamedFramebufer, glGetNamedFramebuffer, or glCheckNamedFramebuffer. The selector-less framebuffer control commands are glFramebufferDrawBufferEXT, glFramebufferDrawBuffersEXT, and glFramebufferReadBufferEXT. Selector-less renderbuffer object commands all start with glNamedRenderbuffer or glGetNamedRenderbuffer. (4) Should the selector-free glTexture* and glNamedProgram* commands and glGetTexture* and glGetNamedProgram* queries have target parameters (for passing GL_TEXTURE_2D or GL_VERTEX_PROGRAM_ARB, etc.)? RESOLVED: Yes. It would be desirable to update a texture parameter for a given texture object without having to know the target of the texture object. For example, one could change the GL_TEXTURE_MIN_FILTER of a texture object without knowing if the texture object was a 1D, 2D, 3D, or cube map texture. As desirable as that might be, OpenGL's texture target scheme makes that difficult in general for several reasons. First, a side-effect of glBindTexture is that a texture object of the indicated target is created if the specified texture object name does not map to an existent texture object. In this case, a texture object of the specified target is created and its state is initialized to the initial texture object state based on the specified target. The selector-free texture object commands should operate the same way if a non-existent texture object is specified. Second, cube maps have face-specific targets (GL_TEXTURE_CUBE_MAP_POSITIVE_X, etc.) as well as the face-independent target (GL_TEXTURE_CUBE_MAP). Commands for texture image specification (glTexImage2D, etc.) and query (glGetTexImage) require the target parameter to select the appropriate face. Assembly program commands have a similar need for a target parameter. Calling glBindProgramARB is specified to create an empty program of the specified target type of the bind. Semantically, glTexture* commands (and glGetTexture* queries) are semantically equivalent of performing a glBindTexture followed atomically by the equivalent glTex* command (or equivalent glGetTex* query). Likewise semantically, glNamedProgram* commands (and glGetNamedProgram* queries) are semantically equivalent of performing a glBindProgramARB followed atomically by the equivalent glProgram* command (or equivalent glGetProgram* query). Note that buffer commands do not have this same need for a target parameter in their selector-less form. (5) The OpenGL API has "latched" state. Explain latched state and how this extension addresses latched state. RESOLVED: Examples of latched state in the OpenGL API are the current array and array element buffers and the pixel store pack/unpack state. Latched stated is all client-side state (pixel store or vertex array). The state of the current array buffer acts as an extra parameter to all the gl*Pointer calls to configure vertex arrays. The state of the current element array buffer acts as an extra parameter to the glDrawElements family of commands. The pixel store unpack state acts as a collection of extra parameters to glTexImage*, glTexSubImage*, glDrawPixels, glBitmap, glColorTable, glPolygonStipple, glConvolutionFilter*, etc. The pixel store pack state acts as a collection of extra parameters to glReadPixels, glGetTexImage, glGetColorTable, etc. Whereas a selector is an extra parameter that designates what state variable is to be updated or queried, latched state is actual state values the command uses to update other state variables or control the operation of the command. Latched state is similar in its undesirability for layered libraries because it requires OpenGL state variables to be modified to update particular state variables or control the operation of the command. Fixing the latched state problem with additional API is involved because it would require introducing a new command for every existing OpenGL command accepting a pointer to specify vertex arrays or pixel data or transform feedback buffer with a "uint buffer, intptr offset" set of parameters rather than a pointer. This extension addresses latched state by adding a new command glClientAttribDefaultEXT that uses its mask parameter to set all the client vertex array or pixel store state to its default state. The glPushClientAttribDefaultEXT performs the glClientAttribDefaultEXT in combination with a glPushClientAttrib command. This provides an inexpensive way to save-and-restore the latched client state so layered libraries that want well-defined latched client state can use these commands. Because the state affected by glPushClientAttribDefaultEXT and glClientAttribDefaultEXT is all client-side, this state is inexpensive to update (unlike the glPushAttrib/glPopAttrib commands). Some consideration was given to providing extra mask bits to control just the vertex array enables (to disable them all) or pixel store pack and unpack state independently (just the pack or just the unpack state). The entire set of vertex array and pixel store state is compact enough that it doesn't make sense to add extra mask bits for subsets of the state. (6) How is the expense of a per-command specified texture object, assembly program object, buffer object, or GLSL program object name lookup minimized? RESOLVED: Modern OpenGL driver implementations implementing this extension are expected to cache most recently used object names so accessing the last name repeatedly is fast. The details of this is left up to the OpenGL implementation but developers can expect consecutive direct access commands to the same named object will be efficient. (7) What should the selector-free glBindTexture routine be called? RESOLVED: glBindMultiTextureEXT This name shares the same "Multi" subword with the other routines (glMultiTexGen*, glMultiTexEnv*, glMultiTexParameter*, etc.). The name uses "MultiTexture" instead of simply "MultiTex" because the glBindMultiTextureEXT command takes a texture object parameter (hence "Texture" instead of "Tex" used for texture unit-based commands) as well as a texture unit parameter. (8) Should glGetIntegeri_v, glGetIntegerIndexedvEXT, glIsEnabledi, glIsEnabledIndexedEXT, etc. work of all query tokens or just query tokens for indexed state such as query tokens where the active texture or client active texture apply? RESOLVED: Just for query tokens for indexed state. This is consistent with how EXT_draw_buffers2 and EXT_transform_feedback work for their Indexed commands. How the index parameter is interpreted depends on the queried state. For texture related state the index refers to the active texture unit or active client texture unit appropriately. Said index texture tokens are: GL_CURRENT_MATRIX_NV GL_CURRENT_MATRIX_STACK_DEPTH_NV GL_CURRENT_RASTER_TEXTURE_COORDS GL_CURRENT_TEXTURE_COORDS GL_TEXTURE_BINDING_1D GL_TEXTURE_BINDING_1D_ARRAY GL_TEXTURE_BINDING_2D GL_TEXTURE_BINDING_2D_ARRAY GL_TEXTURE_BINDING_3D GL_TEXTURE_BINDING_BUFFER_EXT GL_TEXTURE_BINDING_CUBE_MAP GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_NV GL_TEXTURE_BINDING_RECTANGLE_ARB GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT GL_TEXTURE_BUFFER_FORMAT_EXT GL_TEXTURE_COORD_ARRAY GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING GL_TEXTURE_COORD_ARRAY_COUNT GL_TEXTURE_COORD_ARRAY_POINTER GL_TEXTURE_COORD_ARRAY_SIZE GL_TEXTURE_COORD_ARRAY_STRIDE GL_TEXTURE_COORD_ARRAY_TYPE GL_TEXTURE_GEN_Q GL_TEXTURE_GEN_R GL_TEXTURE_GEN_S GL_TEXTURE_GEN_T GL_TEXTURE_MATRIX GL_TEXTURE_STACK_DEPTH GL_TRANSPOSE_TEXTURE_MATRIX GL_TEXTURE_1D GL_TEXTURE_2D GL_TEXTURE_3D GL_TEXTURE_CUBE_MAP GL_TEXTURE_RECTANGLE_ARB For EXT_draw_buffers2 or EXT_transform_feedback queries, the index refers to the draw buffer or transform feedback buffer appropriately. (9) Why does the equivalent code for glGetIntegeri_v, glGetIntegerIndexedvEXT, glIsEnabledi, glIsEnabledIndexedEXT, etc. save and restore the active texture and client active texture state appropriately? RESOLVED: Most query tokens use the active texture but some (those starting with GL_TEXTURE_COORD_ARRAY involving vertex arrays) use the client active texture. For historical reasons, glEnable/glDisable can be used to enable/disable client state that would be better enabled/disabled with glEnableClientState/glDisableClientState. The appropriate selector (active texture or client active texture) is saved or restored based on the query target. (10) Can these selector-free state update commands be compiled into display lists? RESOLVED: YES The object name, texture unit, or matrix mode parameter is compiled into the display list by-value like any other value parameter. This capability to compile selector-free commands into display lists is one of the significant benefits of this extension. Prior to this extension, the only reliable way to update state for a particular texture unit, matrix, buffer, or texture without disturbing OpenGL selector state was using glPushAttrib/glPopAttrib which is too expensive to be practical. However the glGet* selector-free commands, being queries, cannot be compiled into display lists. (11) Why are there no glGetProgramUniform* query commands for GLSL? RESOLVED: OpenGL 2.0 already has glGetUniform* query commands that accept a program parameter as a parameter so are already selector-free. (12) Is glMatrixLoadfEXT(GL_TEXTURE, matrixData), etc. legal? RESOLVED: YES. This will update the texture matrix based on the current active texture. This avoids the matrix mode selector but still relies on the active texture selector. Use GL_TEXTUREn where n is the texture unit to reference a specific texture unit's texture matrix without changing either the matrix mode or active texture state. (13) Some glTex* and glGetTex* routines accept proxy targets. How do proxy textures work with the selector-free commands? RESOLVED: Proxy targets work with the glTex* (glTexImage*) and glGetTex* (glGetTexLevelParameter*) commands that support proxy textures BUT the texture name must be 0 to avoid a GL_INVALID_OPERATION error. This is a consequence of the requirement that the target parameter must match the target of the named texture object. Only the texture object name zero (which exists for all the supported texture targets, including proxies) exists as a proxy target. This should work: GLuint texobj = 0; GLint width; glTexureImage2D(texobj, GL_PROXY_TEXTURE_2D, 0, GL_RGB, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glGetTextureLevelParameterivEXT(texobj, GL_PROXY_TEXTURE_2D, GL_TEXTURE_WIDTH, &width) if (width > 0) { // 32x32 RGB texture supported by implementation } else { // 32x32 RGB texture NOT supported by implementation } This same code would generate a GL_INVALID_OPERATION error if texobj was a non-zero value. (14) What does glClientAttribDefaultEXT(GL_CLIENT_PIXEL_STORE_BIT) do? RESOLVED: It is equivalent to: glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE); glPixelStorei(GL_PACK_LSB_FIRST, GL_FALSE); glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0); glPixelStorei(GL_PACK_SKIP_IMAGES, 0); glPixelStorei(GL_PACK_ROW_LENGTH, 0); glPixelStorei(GL_PACK_SKIP_ROWS, 0); glPixelStorei(GL_PACK_SKIP_PIXELS, 0); glPixelStorei(GL_PACK_ALIGNMENT, 4); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); Note both the pack and unpack state are set to their initial values. Keep in mind that the initial unpack/pack alignment of 4, while the specified initial value, is often surprising to OpenGL developers who expect the alignment to be 1. (15) What does glClientAttribDefaultEXT(GL_CLIENT_VERTEX_ARRAY_BIT) do? RESOLVED: It is equivalent to: int i; GLint max; glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDisableClientState(GL_EDGE_FLAG_ARRAY); glEdgePointer(0, 0); glDisableClientState(GL_INDEX_ARRAY); glIndexPointer(GL_FLOAT, 0, 0); glDisableClientState(GL_SECONDARY_COLOR_ARRAY); glSecondaryColorPointer(4, GL_FLOAT, 0, 0); glDisableClientState(GL_FOG_COORD_ARRAY); glFogCoordPointer(GL_FLOAT, 0, 0); glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max); for (i=0; i