Hi all, below is an attempt to give a starting ground for
a specification to provide texture image specifications and reads
without being affect by GL state.
Comments welcome. Flames mostly welcome.
Name
EXT_stateless_texture_access
Name Strings
GL_EXT_stateless_texture_access
Contributors
Kevin Rogovin, Nomovok
Contact
Kevin Rogovin, Nomovok (kevin.rogovin 'at' nomovok.com)
Status
Draft
Version
Last Modified Date: 11/30/2010 Author revision: 1 Version 0.1
Number
TBD, if ever.
Dependencies
This extension is written against the OpenGL 3.3 specification.
Overview
This extension introduces a set of commands to specify texture
data which are not affected by global GL state. To this end, a
new objec type is introduced so that specifying texture data does
not depend on current GL state, only the state of those objects.
A great deal of the functionality to reduce the affect of GL state
on GL command can be found in GL_EXT_direct_state_access. This
extension provides the following functions:
New Procedures and Functions
uint AllocateTexture1D(enum target, boolean allocate_mipmaps, int internalformat, sizei width);
uint AllocateTexture2D(enum target, boolean allocate_mipmaps, int internalformat, sizei width, sizei height);
uint AllocateTexture3D(enum target, boolean allocate_mipmaps, int internalformat, sizei width, sizei height, sizei depth);
uint AllocateTexture2DMultiSample(enum target, sizei samples, int internalformat, sizei width);
uint AllocateTexture3DMultiSample(enum target, sizei samples, int internalformat, sizei width);
void TextureData1D(uint texture, uint mipmap, int x, sizei width, uint packing_specification, enum format, enum type, uint buffer_object, const void *pixels);
void TextureData2D(uint texture, uint mipmap, int x, int y, sizei width, sizei height, uint packing_specification, uint buffer_object, enum format, enum type, const void *pixels);
void TextureData3D(uint texture, uint mipmap, int x, int y, int z, sizei width, sizei height, sizei depth, uint packing_specification, uint buffer_object, enum format, enum type, const void *pixels);
void GetTextureData1D(uint texture, int x, sizei width, uint unpacking_specification, uint buffer_object, enum format, enum type, void *data);
void GetTextureData2D(uint texture, int x, int y, sizei width, sizei height, uint unpacking_specification, uint buffer_object, enum format, enum type, void *data);
void GetTextureData3D(uint texture, int x, int y, int z, sizei width, sizei height, sizei depth, uint unpacking_specification, uint buffer_object, enum format, enum type, void *data);
enum GetTextureTarget(uint texture);
void UseTexture(uint texture_unit, uint texture);
void UseBufferObjectAsTexture(uint texture_unit, uint buffer_object, sizei offset, GLenum format);
uint CreatePixelStoreSpecification(void);
void DeletePixelStoreSpecification(uint);
void PixelStoreSpecificationParamf(enum pname, float value);
void PixelStoreSpecificationParami(enum pname, int value);
The following functions from GL_EXT_direct_state_access are to be
imported by GL_EXT_stateless_texture_access (shamelessly copy-pasted from the
GL_EXT_direct_state_access extension):
<EXT_texture_integer: New integer texture object commands and queries replace "Tex" in name with "Texture" and add initial "uint texture" parameter>
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);
<OpenGL 3.0: New texture commands add "Texture" within name and replace "enum target" with "uint texture">
void GenerateTextureMipmapEXT(uint texture, enum target);
<OpenGL 3.0: New texture commands add "MultiTex" within name and replace "enum target" with "enum texunit">
void GenerateMultiTexMipmapEXT(enum texunit, enum target);
Additions to Chapter 3 of the OpenGL 3.3 Specification (OpenGL Operation)
Memory for textures maybe allocated through:
uint AllocateTexture1D(enum target, boolean allocate_mipmaps, int internalformat, sizei width);
uint AllocateTexture2D(enum target, boolean allocate_mipmaps, int internalformat, sizei width, sizei height);
uint AllocateTexture3D(enum target, boolean allocate_mipmaps, int internalformat, sizei width, sizei height, sizei depth);
uint AllocateTexture2DMultiSample(enum target, sizei samples, int internalformat, sizei width);
uint AllocateTexture3DMultiSample(enum target, sizei samples, int internalformat, sizei width);
where target refers to a texture target where the allocated texture may
be bound to, internalformat is the internal representation of the texture,
width, height and depth are the dimensions of the texture. For non-multisample
textures, the parameter allocate_mipmaps indicates is to allocate the memory
necessary to store mipmaps. For multisample textures, the parameter samples
refers to the number of samples. Calls to TexImage1D, TexImage2D, TexImage3D,
will generate an GL_INVALID_SOMETHING error if a texture allocated with
one of the above calls is bound to the current texture unit.
GL facilitates the creation and deletion of objects, called
PixelStoreSpecification objects, that store how GL is to
pack and unpack pixel data.
uint CreatePixelStoreSpecification(void);
and destroyed with:
void DeletePixelStoreSpecification(uint);
When created, the PixelStoreSpecification state vector is initiliazed
with the defaults values of GL of PixelStore.
The calls
void PixelStoreSpecificationParamf(uint object, enum pname, float value);
void PixelStoreSpecificationParami(uint object, enum pname, int value);sets a parameter of the PixelStoreSpecification object value named by pname
to the specified value, pname and value pairs are as in PixelStore.
The name 0 is used for the “default” PixelStoreSpecification of GL, it’s values
are unchangeable and is initialized with the default packing and unpacking
value of GL.
Texture may have their texture data modified from the GL client with the commands:
<or should be only those allocated with AllocateTexture1D, AllocateTexture2D, AllocateTexture3D>?
void TextureData1D(uint texture, uint mipmap, int x, sizei width, uint unpacking_specification, enum format, enum type, uint buffer_object, const void *pixels);
void TextureData2D(uint texture, uint mipmap, int x, int y, sizei width, sizei height, uint unpacking_specification, uint buffer_object, enum format, enum type, const void *pixels);
void TextureData3D(uint texture, uint mipmap, int x, int y, int z, sizei width, sizei height, sizei depth, uint unpacking_specification, uint buffer_object, enum format, enum type, const void *pixels);
where texture is the name of the texture, mipmap is the mipmap lod to be modified,
x,y and z are the location of the region to be modified (as in TexSubImage famlily),
width, height and depth specify the size of the region to be modified (as in TexSubImage famlily),
The unpacking_specification is the name of a PixelStoreSpecification parameter determines
how pixels are to be unpacked by GL. The parameter buffer_object is the name of a buffer object
to copy from, with format and type specifying how the data is formated,
pixels refers to an offset with the buffer object to copy data from. If buffer_object
is 0, then pixels is a pointer to client address space.
Texture data may also be read back to a buffer object or client address space via:
void GetTextureData1D(uint texture, int x, sizei width, uint unpacking_specification, uint buffer_object, enum format, enum type, void *data);
void GetTextureData2D(uint texture, int x, int y, sizei width, sizei height, uint unpacking_specification, uint buffer_object, enum format, enum type, void *data);
void GetTextureData3D(uint texture, int x, int y, int z, sizei width, sizei height, sizei depth, uint unpacking_specification, uint buffer_object, enum format, enum type, void *data);
Additionally, pixel data my be read back from the current framebuffer
by specifying texture_name as 0.
The command:
void UseTexture(uint texture_unit, uint texture);
specifies for the named texture_unit to source data from the named texture, texture. The
texture target where a texture is bound to via UseTexture is determined at allocation
of the texture object and can be queried with
enum GetTextureTarget(uint texture);
The command:
void UseBufferObjectAsTexture(uint texture_unit, uint buffer_object, sizei offset, GLenum format);
specifies for the named texture unit to sample data (i.e. sampleBuffer of GLSL)
from the named buffer object starting at the specified offset, format determines
the format of buffer object to sample from.
Issues
(0) What is the status of this extension?
This extension is a proposal from a developer, not from an IHV, as such should
be taken with a huge grain of salt.
(1) What is the purpose of this extension?
The main purpose of the extension is to provide a means to specify texture
data without needing to be aware of any GL state.
(2) Is the state of the PixelStoreSpecification named 0 affected by command PixelStore?
No. The purpose of the PixelStoreSpecification named 0 is to provide a “default”
way for data to be packed and unpacked by GL. Additionally, by having that object
affected by PixelStore commands, then the interpretation of TextureData depends on
the current GL state, which this extension is aiming to remove.
(3) What is the point to UseBufferObjectAsTexture?
It’s main purpose is for a developer to see directly in code the source of data.
Additionally, it also provides an offset into the buffer object to… one can argue
that one can add such to GL_EXT_texture_buffer_object as well, but UseBufferObjectAsTexture
removes a layer of (I feel) unnecessary indirection. In brutal honesty, the call
is inspired by NV_shader_buffer_load 's ability to set uniforms to “pointers”.
(4) How does the GenerateMipmap family of functions interact with texture allocated
by the new entry points? I.e. what is the expected behavour of calling GenerateMipmap
on a texture allocated with the new call but with allocated so that mipmaps are not?
Unresolved. There are several options:
i) Textures allocated with one of the new calls can also have
the glTexImage family of functions affect them. The question then
becomes, do GL implementors lose potential performance or does
the GL implementation burden increase?
ii) GenerateMipmap acts as always, i.e. if a texture was allocated
without mipmaps, then GenerateMipmap will allocate and generate them.
This though violates the idea that the texture allocation call
specifies the memory required by the texture object for it’s lifetime.
iii) GenerateMiapmap generates an error for those textures allocated
with the new allocation calls that specify to not allocate mipmaps.
The issue with the solution is that then GenerateMiapmap acts differently
on how the texture was created.
iv) GenerateMiapmap cannot be used with such textures, instead a new call
to generate the mipmaps must be used. This has the advantage of being
self consistent. The disadvantage is that it again places textures into
2 classes: those allocated with the new calls and those allocated with
TexImage.
(5) Given that the texture target (which is really a texture type) is specified
at allocation, it seems unnecessary that the direct_state_access TexParameter
family of functions need the texture target when manipulating a texture allocated
with one of the new calls.
The simple lazy answer is: “don’t worry about it and use GetTextureTarget” for
such textures. Potentially added new TexParamter calls that don’t require
a texture target parameter.
(6) How does GetTextureTarget behave for those texture names retrieved
from GenTextures that have not been allocated via a TexImage call yet?
Returns GL_INVALID_ENUM.
(7) How does TextureData family of functions behave for such texture
names as asked about in Issue (6)?
Generate an error analogous to calling TexSubImage acting on such textures.
More generally speaking, one can view the TextureData entry points as
a “stateless” version of the TexSubImage calls.