Name NV_explicit_multisample Name Strings GL_NV_explicit_multisample Contributors Eric Werness, NVIDIA Corporation Pat Brown, NVIDIA Corporation Jamie Gennis, NVIDIA Corporation Nacho Sanz-Pastor, Aechelon Mark Kilgard, NVIDIA Corporation Contact Eric Werness, NVIDIA Corporation (ewerness 'at' nvidia.com) Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com) Status Shipping in NVIDIA's Release 180 drivers (October 2008) Version Last Modified Date: 10/27/08 Revision: 1 Number 357 Dependencies OpenGL 2.0 is required. ARB_multisample is required. EXT_framebuffer_multisample affects the definition of this extension. NV_gpu_program4 affects the definition of this extension. EXT_gpu_shader4 affects the definition of this extension. EXT_timer_query affects the definition of this extension. This extension is written against the OpenGL 2.0 specification. Overview In traditional multisample specs, the API only allows access to the samples indirectly through methods such as coverage values and downsampled readbacks. NV_explicit_multisample adds a set of new capabilities to allow more precise control over the use of multisamples. Specifically, it adds: * A query in the API to query the location of samples within the pixel * An explicit control for the multisample sample mask to augment the control provided by SampleCoverage * A new texture target to wrap a renderbuffer and allow a restricted class of accesses to the samples * The ability to fetch a specific sample from a multisampled texture from within a shader * A program option to enable the new behavior New Procedures and Functions void GetBooleanIndexedvEXT(enum value, uint index, boolean *data); void GetIntegerIndexedvEXT(enum value, uint index, int *data); void GetMultisamplefvNV(enum pname, uint index, float *val); void SampleMaskIndexedNV(uint index, bitfield mask); void TexRenderbufferNV(enum target, uint renderbuffer); New Tokens Accepted by the parameter of GetMultisamplefvNV: SAMPLE_POSITION_NV 0x8E50 Accepted by the parameter of Enable, Disable, and IsEnabled, and by the parameter of GetBooleanv, GetIntegerv, GetFloatv, and GetDoublev: SAMPLE_MASK_NV 0x8E51 Accepted by the parameter of GetBooleanIndexedvEXT and GetIntegerIndexedvEXT: SAMPLE_MASK_VALUE_NV 0x8E52 Accepted by the parameter of GetBooleanv, GetDoublev, GetIntegerv, and GetFloatv: TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 MAX_SAMPLE_MASK_WORDS_NV 0x8E59 Accepted by the parameter of BindTexture, and TexRenderbufferNV: TEXTURE_RENDERBUFFER_NV 0x8E55 Returned by the parameter of GetActiveUniform: SAMPLER_RENDERBUFFER_NV 0x8E56 INT_SAMPLER_RENDERBUFFER_NV 0x8E57 UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 Additions to Chapter 2 of the OpenGL 2.0 Specification (OpenGL Operation) Modify Section 2.X.2, Program Grammar If a program specifies the NV_explicit_multisample program option, the rule is modified to add the texture target RENDERBUFFER and the rule is modified to add the instruction TXFMS. Add to section 2.15.4.1, Shader Only Texturing Multisample Texel Fetches Multisample texel fetches are very similar to standard texel fetches. Since multisample buffers can't have mipmaps, there is no LOD parameter. Instead, there is an integer parameter which selects the sample number to be fetched from the buffer. The number identifying the sample is the same as the value used to query the sample location using GetMultisamplefvNV. Additionally, this fetch may only be performed on a texture renderbuffer sampler. No other sample or fetch commands may be performed on a texture renderbuffer sampler. Add to section 2.X.4.4, Program Texture Access Add row to table X.17 coordinates used texTarget Texture Type s t r layer shadow ---------------- --------------------- ----- ----- ------ RENDERBUFFER TEXTURE_RENDERBUFFER_NV Add row to table X.18 coordinates used texTarget supported i j k layer lod ---------------- --------- ----- ----- --- RENDERBUFFER no - - - - - Add after the discussion of TexelFetch The TXFMS instruction provides the ability to extract a single sample from a specified RENDERBUFFER texture image using the function result_t_vec TexelFetchMultisample(int_vec coord, int_vec offset); The extracted texel is converted to an (R,G,B,A) vector according to Table 3.21. The result vector is interpreted as floating-point, signed integer, or unsigned integer, according to the data type modifier of the instruction. If the internal format of the texture is not compatible with the instruction's data type modifier, the extracted texel value is undefined. is a four-component signed integer vector used to identify the single sample accessed. Since a renderbuffer must be 2D with no mipmaps, the x and y components are always used to select the pixel and the fourth component is used to select the sample. All of the restrictions of TexelFetch apply to TexelFetchMultisample, with the additional requirement that it must be called on a RENDERBUFFER texture target. If the sample number is greater than or equal to the value of SAMPLES for the render buffer associated with the renderbuffer texture, the results are undefined. Additions to Chapter 3 of the OpenGL 2.0 Specification (Rasterization) (Insert into section 3.2.1, Multisampling after the discussion of the query for SAMPLES) To query the location of a given sample, the function void GetMultisamplefvNV(enum pname, uint index, float *val); is used with a pname of SAMPLE_POSITION_NV and an index corresponding to the sample for which the location should be returned. The sample location is returned as two floating point values each between 0 and 1 corresponding to the x and y locations respectively in GL pixel space of that sample. The error INVALID_OPERATION is generated if is greater than or equal to the value of SAMPLES. (Insert new Section 3.8.4, Renderbuffer Textures. Renumber subsequent sections.) In addition to one-, two-, and three-dimensional and cube map textures described in previous sections, one additional type of texture is supported. A renderbuffer texture is similar to a two-dimensional texture. However, unlike other texture types, the texel array is not stored as part of the texture. Instead, a renderbuffer object is attached to a renderbuffer texture and the texel array is taken from the data store of the attached renderbuffer object. When the contents of a renderbuffer are modified, those changes are reflected in the contents of any renderbuffer texture to which the buffer object is attached. Also unlike other textures, renderbuffer textures do not have multiple image levels; only a single data store is available. The command void TexRenderbufferNV(enum target, uint renderbuffer); attaches the renderbuffer object named to the active renderbuffer texture. If is zero, any renderbuffer object attached to the buffer texture is detached, and no new renderbuffer object is attached. If is non-zero, but is not the name of an existing renderbuffer object, the error INVALID_OPERATION is generated. must be TEXTURE_RENDERBUFFER_NV. The name of the renderbuffer object that is bound as the data store of the active renderbuffer texture can be queried by calling GetIntegerv with set to TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV. When a renderbuffer texture is accessed in a shader, the access takes one vector of integers describing which pixel to fetch and an integer corresponding to the sample numbers described in section 3.2.1 describing which sample within the pixel to fetch. No standard sampling instructions are allowed to the renderbuffer texture target. Modify Section 3.8.10, Texture Completeness (p. 177) (insert after second paragraph of section, p.177) For renderbuffer textures, a texture is if a renderbuffer object is attached to it, and each dimension of that renderbuffer is positive. Modify Section 3.8.11, Texture State and Proxy State (p. 178) (insert into the first paragraph of the section, p. 178) ... a zero compressed size, and zero-sized components). The renderbuffer texture target contains an integer identifying the renderbuffer object that provides the data store for the texture, initially zero. Next, there are the two sets of texture properties; ... Modify Section 3.8.12, Texture Objects (p. 180) (modify first paragraphs of section, p. 180, simply adding references to renderbuffer textures, which are treated as texture objects) In addition to the default textures TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_CUBE_MAP, and TEXTURE_RENDERBUFFER_NV, named one-, two-, and three-dimensional, cube map, and renderbuffer texture objects can be created and operated upon. The name space for texture objects is the unsigned integers, with zero reserved by the GL. A texture object is created by binding an unused name to TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_CUBE_MAP, or TEXTURE_RENDERBUFFER_NV. The binding is effected by calling void BindTexture( enum target, uint texture ); with target set to the desired texture target and texture set to the unused name. The resulting texture object is a new state vector, comprising all the state values listed in section 3.8.11, set to the same initial values. If the new texture object is bound to TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_CUBE_MAP, or TEXTURE_RENDERBUFFER_NV, it is and remains a one-, two-, three-dimensional, cube map, or renderbuffer texture respectively until it is deleted. BindTexture may also be used to bind an existing texture object to either TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_CUBE_MAP, or TEXTURE_RENDERBUFFER_NV. The error INVALID_OPERATION is generated if an attempt is made to bind a texture object of different dimensionality than the specified target. If the bind is successful no change is made to the state of the bound texture object, and any previous binding to target is broken. ... In the initial state, TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_CUBE_MAP, and TEXTURE_RENDERBUFFER_NV have one-, two-, three-dimensional, cube map, and renderbuffer texture state vectors respectively associated with them. In order that access to these initial textures not be lost, they are treated as texture objects all of whose names are 0. The initial one-, two-, three-dimensional, cube map, and renderbuffer texture is therefore operated upon, queried, and applied as TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_CUBE_MAP, or TEXTURE_RENDERBUFFER_NV respectively while 0 is bound to the corresponding targets. Texture objects are deleted by calling void DeleteTextures( sizei n, uint *textures ); textures contains n names of texture objects to be deleted. After a texture object is deleted, it has no contents or dimensionality, and its name is again unused. If a texture that is currently bound to one of the targets TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_CUBE_MAP, or TEXTURE_RENDERBUFFER_NV is deleted, it is as though BindTexture had been executed with the same target and texture zero. Unused names in textures are silently ignored, as is the value zero. (modify second paragraph, p. 182, adding buffer textures, plus cube map textures, which is an oversight in the core specification) The texture object name space, including the initial one-, two-, and three-dimensional, cube map, and renderbuffer texture objects, is shared among all texture units. A texture object may be bound to more than one texture unit simultaneously. After a texture object is bound, any GL operations on that target object affect any other texture units to which the same texture object is bound. Additions to Chapter 4 of the OpenGL 2.0 Specification (Per-Fragment Operations and the Frame Buffer) Modify Section 4.1.3, Multisample Fragment Operations Modify the first paragraph to include SAMPLE_MASK and SAMPLE_MASK_VALUE on the list of values the coverage value is modified based on. Modify the discussion of SAMPLE_COVERAGE to start with "Next" instead of "Finally" Add after the discussion of SAMPLE_COVERAGE: Finally, if SAMPLE_MASK is enabled, the fragment coverage is ANDed with the coverage value SAMPLE_MASK_VALUE. The value of SAMPLE_MASK_VALUE is specified using void SampleMaskIndexedNV(GLuint index, GLbitfield mask); with set to the desired mask for . SAMPLE_MASK_VALUE is queried by calling GetIntegerIndexedv with set to SAMPLE_MASK_VALUE and the index set to . Bit B of mask M corresponds to sample 32*M+B as described in Section 3.2.1. The error INVALID_OPERATION is generated if the mask word indexed is greater than or equal to MAX_SAMPLE_MASK_WORDS. Additions to Chapter 5 of the OpenGL 2.0 Specification (Special Functions) On p. 241, add the following to the list of commands not compiled into a display list: GetMultisamplefvNV, TexRenderbufferNV. Additions to Chapter 6 of the OpenGL 2.0 Specification (State and State Requests) Modify the second paragraph of section 6.1.1 (Simple Queries) p244 to read as follows: ... is a pointer to a scalar or array of the indicated type in which to place the returned data. void GetBooleanIndexedvEXT(enum target, uint index, boolean *data); void GetIntegerIndexedvEXT(enum target, uint index, int *data); are used to query indexed state. is the name of the indexed state and is the index of the particular element being queried. is a pointer to a scalar or array of the indicated type in which to place the returned data. In addition ... Additions to the AGL/GLX/WGL Specifications None GLX Protocol The following rendering command is sent to the server as part of a glXRender request: SampleMaskIndexedNV 2 12 rendering command length 2 XXXX rendering command opcode 4 CARD32 index 4 BITFIELD mask TexRenderbufferNV 2 12 rendering command length 2 XXXX rendering command opcode 4 ENUM target 4 CARD32 renderbuffer The following new non-rendering commands are added: GetMultisamplefvNV 1 CARD8 opcode(X assigned) 1 XXX GLX opcode 2 4 request length 4 GLX_CONTEXT_TAG context tag 4 ENUM pname 4 CARD32 index => 1 1 reply 1 unused 2 CARD16 sequence number 4 0 reply length 8 unused 4 FLOAT32 val[0] 4 FLOAT32 val[1] 8 unused Dependencies on EXT_framebuffer_multisample If EXT_framebuffer_multisample is not available, all discussion involving textures and renderbuffers is deleted. This only leaves the ability to query the sample parameters of the current framebuffer. Dependencies on EXT_timer_query If EXT_timer_query is not available, include its discussion of int64EXT and uint64EXT. Dependencies on NV_gpu_program4 and EXT_gpu_shader4 If NV_gpu_program4 and EXT_gpu_shader4 are not supported, and no other mechanism is provided to perform texture lookups into renderbuffer textures, this extension is pointless, given that it provides no fixed-function mechanism to access renderbuffer textures. If EXT_gpu_shader4 is supported, the language below describes the modifications to the shading language to support renderbuffer textures. If not, the language below and in Chapter 2 should be removed. Errors The error INVALID_VALUE is generated by GetBooleanIndexedvEXT and GetIntegerIndexedvEXT if target is SAMPLE_MASK_VALUE_NV and index is greater than or equal to MAX_SAMPLE_MASK_WORDS_NV. The error INVALID_VALUE is generated by SampleMaskIndexedNV if index is greater than or equal to MAX_SAMPLE_MASK_WORDS_NV. New State Get Value Get Command Type Initial Value Attribute --------- ----------- ---- ------------- --------- SAMPLE_MASK_NV IsEnabled B FALSE multisample/enable SAMPLE_MASK_VALUE_NV GetInteger- nxZ+ ~0 multisample IndexedvEXT Where n is the number of sample mask words (the value of MAX_SAMPLE_MASK_WORDS_NV) the implementation supports. (add to table 6.15, Texture State Per Texture Unit/Binding Point p. 276) Initial Get Value Type Get Command Value Description Sec. Attribute --------------------------------- ---- ----------- ------- --------------------------- ------ --------- TEXTURE_BINDING_RENDERBUFFER_NV 2*xZ+ GetIntegerv 0 Texture object bound to 3.8.12 texture TEXTURE_RENDERBUFFER_EXT (add to table 6.16, Texture State Per Texture Object, p. 276) Initial Get Value Type Get Command Value Description Sec. Attribute --------------------------------- ---- ----------- ------- --------------------------- ------ --------- TEXTURE_RENDERBUFFER_DATA_STORE_ nxZ+ GetIntegerv 0 Renderbuffer object bound 3.8.4 texture BINDING_NV as the data store for the active image unit's renderbuffer texture (add to table 9.nnn "Framebuffer dependent Values" introduced by the EXT_framebuffer_object specification) Initial Get Value Type Get Command Value Description Sec. Attribute ------------------ ---------- ------------------ -------------- --------------- ------ --------- SAMPLE_POSITION_NV N*2*R[0,1] GetMultisamplefvNV implementation Explicit sample 3.2.1 - dependent positions Where N is the number of samples (the value of SAMPLES) the framebuffer supports. New Implementation Dependent State Minimum Get Value Type Get Command Value Description Sec. Attribute --------- ------- ----------- ------- ---------------- ------ --------- MAX_SAMPLE_MASK_WORDS_NV Z GetIntegerv 1 maximum number x.x.x - of sample mask words Modifications to the OpenGL Shading Language Specification, Version 1.10.59 Including the following line in a shader can be used to control the language featured described in this extension: #extension GL_NV_explicit_multisample : where is as specified in section 3.3. A new preprocessor #define is added to the OpenGL Shading Language: #define GL_NV_explicit_multisample 1 Add to section 3.6 "Keywords" The following new sampler types are added: samplerRenderbuffer, isamplerRenderbuffer, usamplerRenderbuffer Add to section 4.1 "Basic Types" Add the following sampler type to the "default sampler types" table: samplerRenderbuffer handle for accessing a renderbuffer texture Add the following sampler type to the "unsigned integer sampler types" table: isamplerRenderbuffer handle for accessing an integer renderbuffer texture Add the following sampler type to the "integer sampler types" table: usamplerRenderbuffer handle for accessing an unsigned integer renderbuffer texture Add to section 8.7 "Texture Lookup Functions" Add new functions to the set of allowed texture lookup functions: Syntax: vec4 texelFetchRenderbuffer(samplerRenderbuffer sampler, ivec2 coord, int sample) Description: Use integer texture coordinate to lookup a single sample on the texture bound to as described in section 2.15.4.1 of the OpenGL specification "Multisample Texel Fetches". Syntax: ivec2 textureSizeRenderbuffer(samplerRenderbuffer sampler) ivec2 textureSizeRenderbuffer(isamplerRenderbuffer sampler) ivec2 textureSizeRenderbuffer(usamplerRenderbuffer sampler) Description: Returns the dimensions, width and height of level 0 for the texture bound to , as described in section 2.15.4.1 of the OpenGL specification section "Texture Size Query". Examples Issues (1) Should the NUMBER_OF_SAMPLES parameter reuse an existing enum? RESOLVED. Just use SAMPLES_ARB. (2) How should we deal with sample patterns of more than sizeof(GLbitfield)*8 bits for the sample mask? RESOLVED. The API uses indexed calls to allow indefinite extension of the number of samples exposed. (3) What's the interaction between sample mask, sample coverage, and alpha to coverage? UNRESOLVED. In the hardware there's just one method for doing overall coverage, so we can combine the two API states into the methods as we see fit. The more interesting question is the interaction between the shader sample mask from GPU_program4_1 and the API-level masks, which we should try to keep similar to the API-level interface. (4) Should we expose the CSAA weights in this API? RESOLVED. Not in this extension. For now, only maskable samples can be queried. A future extension can allow this functionality. (5) What should the default value of SAMPLE_MASK be? 0? ~0? RESOLVED. ~0 to match with other state like stencil mask. (6) Should the sample position query work for non-multisample? RESOLVED. The value of SAMPLES for non-multisample is zero, so the sample position query will return an error for all index values in this case. (7) Integer/unsigned integer renderbuffer sampler types? RESOLVED. There are integer/unsigned integer renderbuffer sampler types. (8) Do we need a program option to enable the new behavior? RESOLVED. Yes. (9) What should TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV be if the renderbuffer object it refers to has been deleted? RESOLVED. TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV remains unchanged when the renderbuffer is deleted. (10) Do renderbuffer textures support texture parameters (TexParameter) or queries (GetTexParameter, GetTexLevelParameter, GetTexImage)? RESOLVED: No. None of the existing parameters apply to renderbuffer textures, and this extension doesn't introduce the need for any new ones. Renderbuffer textures have no levels, and the size in texels is implicit (based on the data store). Given that the texels themselves are obtained from a renderbuffer object, it seems more appropriate to retrieve such data with renderbuffer queries. Note that the spec edits above don't add explicit error language for any of these cases. That is because each of the functions enumerate the set of valid parameters. Not editing the spec to allow TEXTURE_RENDERBUFFER_NV in these cases means that target is not legal, and an INVALID_ENUM error should be generated. (11) What is the behavior of TexelFetchMultisample when given an out-of-bounds value? RESOLVED: Undefined. This spec explicitly lists the behavior as undefined when given a sample number greater than SAMPLES-1 and inherits the undefined behavior specified for TexelFetch when the normal two-dimensional coordinate is outside the range of the texture. Revision History Rev. Date Author Changes ---- -------- -------- ----------------------------------------- 1 7/22/08 ewerness First revision.