• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    EXT_multisampled_render_to_texture
4
5Name Strings
6
7    GL_EXT_multisampled_render_to_texture
8
9Contributors
10
11    Georg Kolling, Imagination Technologies (georg.kolling 'at' imgtec.com)
12    Ben Bowman, Imagination Technologies (benji.bowman 'at' imgtec.com)
13
14Contact
15
16    Jan-Harald Fredriksen (jan-harald.fredriksen 'at' arm.com)
17
18Status
19
20    Complete
21
22Version
23
24    Last Modified Date: June 28, 2016
25    Revision: 7
26
27Number
28
29    OpenGL ES Extension #106
30
31Dependencies
32
33    OpenGL ES 2.0 or OES_framebuffer_object are required. This
34    extension is written against the OpenGL ES 2.0 Specification.
35
36    This extension interacts with OpenGL ES 3.0 and later versions.
37
38Overview
39
40    This extension introduces functionality to perform multisampled
41    rendering to a color renderable texture, without requiring an
42    explicit resolve of multisample data.
43
44    Some GPU architectures - such as tile-based renderers - are
45    capable of performing multisampled rendering by storing
46    multisample data in internal high-speed memory and downsampling the
47    data when writing out to external memory after rendering has
48    finished. Since per-sample data is never written out to external
49    memory, this approach saves bandwidth and storage space. In this
50    case multisample data gets discarded, however this is acceptable
51    in most cases.
52
53    The extension provides a new command, FramebufferTexture2DMultisampleEXT,
54    which attaches a texture level to a framebuffer and enables
55    multisampled rendering to that texture level.
56
57    When the texture level is flushed or used as a source or destination
58    for any operation other than drawing to it, an implicit resolve of
59    multisampled color data may be performed. After such a resolve, the
60    multisampled color data is discarded.
61
62    In order to allow the use of multisampled depth and stencil buffers
63    when performing multisampled rendering to a texture, the extension
64    also adds the command RenderbufferStorageMultisampleEXT.
65
66IP Status
67
68    No known IP claims.
69
70New Procedures and Functions
71
72    void RenderbufferStorageMultisampleEXT(
73            enum target, sizei samples,
74            enum internalformat,
75            sizei width, sizei height);
76
77    void FramebufferTexture2DMultisampleEXT(
78            enum target, enum attachment,
79            enum textarget, uint texture,
80            int level, sizei samples);
81
82New Tokens
83
84    Accepted by the <pname> parameter of GetRenderbufferParameteriv:
85
86        RENDERBUFFER_SAMPLES_EXT                    0x8CAB
87
88    Returned by CheckFramebufferStatus:
89
90        FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT      0x8D56
91
92    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
93    and GetFloatv:
94
95        MAX_SAMPLES_EXT                             0x8D57
96
97    Accepted by the <pname> parameter of GetFramebufferAttachmentParameteriv:
98
99        FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT  0x8D6C
100
101
102Additions to Section 4.4.3 of the OpenGL ES 2.0 Specification
103(Renderbuffer Objects)
104
105    Replace the paragraph describing the command RenderbufferStorage
106    with the following:
107
108        The command
109            void RenderbufferStorageMultisampleEXT( enum target,
110                sizei samples, enum internalformat, sizei width,
111                sizei height );
112        establishes the data storage, format, dimensions, and number of
113        samples of a renderbuffer object's image. target must be RENDERBUFFER.
114        internalformat must be one of the color-renderable, depth-renderable,
115        or stencil-renderable formats described in table 4.5. width and height
116        are the dimensions in pixels of the renderbuffer. If either width or
117        height is greater than the value of MAX_RENDERBUFFER_SIZE, or if
118        samples is greater than the value of MAX_SAMPLES_EXT, then the error
119        INVALID_VALUE is generated. If OpenGL ES is unable to create a data
120        store of the requested size, the error OUT_OF_MEMORY is generated.
121        Upon success, RenderbufferStorageMultisampleEXT deletes any existing
122        data store for the renderbuffer image and the contents of the data
123        store after calling RenderbufferStorageMultisampleEXT are undefined.
124        RENDERBUFFER_WIDTH is set to width, RENDERBUFFER_HEIGHT is set to
125        height, and RENDERBUFFER_INTERNAL_FORMAT is set to internalformat.
126        If samples is zero, then RENDERBUFFER_SAMPLES_EXT is set to zero.
127        Otherwise samples represents a request for a desired minimum number
128        of samples. Since different implementations may support different
129        sample counts for multisampled rendering, the actual number of samples
130        allocated for the renderbuffer image is implementation-dependent.
131        However, the resulting value for RENDERBUFFER_SAMPLES_EXT is
132        guaranteed to be greater than or equal to samples and no more than the
133        next larger sample count supported by the implementation.
134
135        When the renderbuffer is used as a source or destination for any
136        operation, when the attachment is flushed, or when the attachment is
137        broken, an implicit resolve of the multisample data may be performed.
138        After such a resolve, the contents of the multisample buffer become
139        undefined. The operations that may cause an implicit resolve are the
140        same as for FramebufferTexture2DMultisampleEXT.
141
142        An OpenGL ES implementation may vary its allocation of internal
143        component resolution based on any RenderbufferStorageMultisampleEXT
144        parameter (except target), but the allocation and chosen internal format
145        must not be a function of any other state and cannot be changed once
146        they are established.
147
148        The command
149            void RenderbufferStorage( enum target, enum internalformat,
150                sizei width, sizei height );
151        is equivalent to calling RenderbufferStorageMultisampleEXT with
152        samples equal to zero.
153
154    Add the following after the paragraph describing FramebufferTexture2D:
155
156        The command
157            void FramebufferTexture2DMultisampleEXT( enum target,
158                enum attachment, enum textarget, uint texture,
159                int level, sizei samples );
160        enables multisampled rendering into the images of a texture object.
161
162        target, textarget, texture, and level correspond to the same
163        parameters for FramebufferTexture2D and have the same restrictions.
164        attachment must be COLOR_ATTACHMENT0. If samples is greater than the
165        value of MAX_SAMPLES_EXT, then the error INVALID_VALUE is generated.
166        An INVALID_OPERATION error is generated if samples is greater than
167        the maximum number of samples supported for target and its
168        internalformat. If samples is zero, then TEXTURE_SAMPLES_EXT is set
169        to zero, and FramebufferTexture2DMultisampleEXT behaves like
170        FramebufferTexture2D.
171
172        Otherwise samples represents a request for a desired minimum number
173        of samples. Since different implementations may support different
174        sample counts for multisampled rendering, the actual number of samples
175        allocated for the image is implementation-dependent. However, the
176        resulting value for TEXTURE_SAMPLES_EXT is guaranteed to be greater
177        than or equal to samples and no more than the next larger sample count
178        supported by the implementation.
179
180        The implementation allocates an implicit multisample buffer with
181        TEXTURE_SAMPLES_EXT samples and the same internalformat, width, and
182        height as the specified texture level. This buffer is used as the
183        target for rendering instead of the specified texture level. The
184        buffer is associated with the attachment and gets deleted after the
185        attachment is broken.
186
187        While the implicit multisample buffer is attached, color sample values
188        are automatically resolved to a single color in the texture level each
189        time a pixel is updated. This has the effect of making the antialiasing
190        appear to be automatic at the application level.
191
192        When the texture level is used as a source or destination for any
193        operation, the attachment is flushed, or when the attachment is broken,
194        the GL implementation may discard the contents of the implicit multisample
195        buffer. If the contents are discarded, the subsequent operations on the
196        multisample buffer will behave as if all samples within a pixel have the
197        value most recently written to the color buffer for that pixel.
198
199        The operations which may cause the contents of the implicit multisample
200        buffer to be discarded include:
201            - Drawing with the texture bound to an active texture unit
202            - ReadPixels or CopyTex[Sub]Image* while the texture is
203              attached to the framebuffer
204            - CopyTex[Sub]Image*, Tex[Sub]Image*,
205              CompressedTex[Sub]Image* with the specified level as
206              destination
207            - GenerateMipmap
208            - Flush or Finish while the texture is attached to the
209              framebuffer
210            - BindFramebuffer while the texture is attached to the currently
211              bound framebuffer.
212
213
214Additions to section 4.4.5 of the OpenGL ES 2.0 Specification
215(Framebuffer Completeness)
216
217    Add the following bullet point to the list of conditions for
218    Framebuffer Attachment Completeness:
219
220       * The number of texture samples (as set by FramebufferTexture2DMultisampleEXT)
221         must be less than or equal to the maximum number of samples supported for
222         the  internal format of _image_.
223
224    Add the following bullet point after
225        * All attached images have the same width and height.
226          FRAMEBUFFER_INCOMPLETE_DIMENSIONS
227    on page 116:
228
229        * The value of RENDERBUFFER_SAMPLES_EXT is the same for all
230          attached renderbuffers; the value of TEXTURE_SAMPLES_EXT
231          is the same for all texture attachments; and, if the attached
232          images are a mix of renderbuffers and textures, the value of
233          RENDERBUFFER_SAMPLES_EXT matches the value of TEXTURE_-
234          SAMPLES_EXT.
235          FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
236
237Dependencies on GL and ES profiles, versions, and other extensions
238
239    Interactions with OpenGL ES 3.0 and later versions:
240
241        If OpenGL ES 3.0 or later is not supported, ignore all references
242        to DRAW_FRAMEBUFFER and READ_FRAMEBUFFER.
243
244        The OpenGL ES 3.1 specification states that:
245        "An INVALID_OPERATION error is generated by CopyTexSubImage3D,
246         CopyTexImage2D, or CopyTexSubImage2D if
247         ...
248         * the value of READ_FRAMEBUFFER_BINDING is non-zero, and
249           - the read buffer selects an attachment that has no image attached,
250             or
251           - the value of SAMPLE_BUFFERS for the read framebuffer is one."
252
253        Similarly, for ReadPixels:
254        "An INVALID_OPERATION error is generated if the value of READ_-
255         FRAMEBUFFER_BINDING (see section 9) is non-zero, the read framebuffer
256         is framebuffer complete, and the value of SAMPLE_BUFFERS for the read
257         framebuffer is one."
258
259        These errors do not apply to textures and renderbuffers that have
260        associated multisample data specified by the mechanisms described in
261        this extension, i.e., the above operations are allowed even when
262        SAMPLE_BUFFERS is non-zero for renderbuffers created via Renderbuffer-
263        StorageMultisampleEXT or textures attached via FramebufferTexture2D-
264        MultisampleEXT.
265
266        Also, FBOs cannot combine attachments that have associated multisample
267        data specified by the mechanisms described in this extension with
268        attachments allocated using the core OpenGL ES 3.1 mechanisms, such as
269        TexStorage2DMultisample. Add to section 9.4.2 "Whole Framebuffer
270        Completeness":
271        "* If the value of RENDERBUFFER_SAMPLES is non-zero, all or none of the
272           attached renderbuffers have been allocated using RenderbufferStorage-
273           MultisampleEXT; if the value of TEXTURES_SAMPLES is non-zero, all or
274           none of the attached textures have been attached using Framebuffer-
275           Texture2DMultisampleEXT.
276           { GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT }"
277
278       Add to the description of FramebufferTexture2DMultisampleEXT (first
279       paragraph):
280           "The maximum number of samples supported can be determined by calling
281           GetInternalformativ with a pname of SAMPLES."
282
283Errors
284
285    The error OUT_OF_MEMORY is generated when
286    RenderbufferStorageMultisampleEXT cannot create storage of the
287    specified size.
288
289    If RenderbufferStorageMultisampleEXT is called with a value of
290    <samples> that is greater than MAX_SAMPLES_EXT, then the error
291    INVALID_VALUE is generated.
292
293    The error INVALID_ENUM is generated if FramebufferTexture2DMultisampleEXT
294    is called with a <target> that is not FRAMEBUFFER, DRAW_FRAMEBUFFER, or
295    READ_FRAMEBUFFER.
296
297    The error INVALID_ENUM is generated if FramebufferTexture2DMultisampleEXT
298    is called with an <attachment> that is not COLOR_ATTACHMENT0.
299
300    The error INVALID_ENUM is generated if FramebufferTexture2DMultisampleEXT
301    is called with a <textarget> that is not TEXTURE_2D,
302    TEXTURE_CUBE_MAP_POSITIVE_X, TEXTURE_CUBE_MAP_POSITIVE_Y,
303    TEXTURE_CUBE_MAP_POSITIVE_Z, TEXTURE_CUBE_MAP_NEGATIVE_X,
304    TEXTURE_CUBE_MAP_NEGATIVE_Y, or TEXTURE_CUBE_MAP_NEGATIVE_Z.
305
306    The error INVALID_OPERATION is generated if FramebufferTexture2DMultisampleEXT
307    is called with <samples> greater than the maximum number of samples supported
308    for <target> and its internalformat.
309
310New State
311
312	Changes to table 6.22, p. 154 (Renderbuffer State)
313
314                                                     Initial
315    Get Value                 Type  Get Command      Value   Description  Sec.
316    ---------                 ----  ---------------- ------- ------------ -----
317    RENDERBUFFER_SAMPLES_EXT  Z+    GetRenderbuffer- 0       Renderbuffer 4.4.3
318                                    Parameteriv              samples
319
320	Changes to table 6.23, p. 155 (Framebuffer State)
321
322                                                       Initial
323    Get Value            Type    Get Command           Value   Description     Sec.
324    ---------            ------  --------------------- ------- --------------- ----
325    TEXTURE_SAMPLES_EXT  n * Z+  GetFramebuffer-       0       Framebuffer     4.4
326                                 AttachmentParameteriv         texture samples
327
328New Implementation Dependent State
329
330    Changes to table 6.17, p. 149 (Implementation Dependent Values)
331
332                                          Minimum
333    Get Value         Type    Get Command Value   Description Sec.
334    ---------         ----    ----------- ------- ----------- ----
335    MAX_SAMPLES_EXT   Z+      GetIntegerv 2       Max. # of   4.4
336                                                  samples.
337
338Sample Code
339
340	GLsizei width  = ...;
341	GLsizei height = ...;
342	GLint samples;
343	glGetIntegerv(GL_MAX_SAMPLES_EXT, &samples);
344
345	/* Create multisampled depth renderbuffer */
346	GLuint depthbuffer;
347	glGenRenderbuffers(1, &depthbuffer);
348	glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer);
349	glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
350		GL_DEPTH_COMPONENT16, width, height);
351	glBindRenderbuffer(GL_RENDERBUFFER, 0);
352
353	/* Create RGBA texture with single mipmap level */
354	GLuint texture;
355	glGenTextures(1, &texture);
356	glBindTexture(GL_TEXTURE_2D, texture);
357	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
358		GL_UNSIGNED_SHORT_4_4_4_4, NULL);
359	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
360	glBindTexture(GL_TEXTURE_2D, 0);
361
362	/* Create framebuffer object, attach texture and depth renderbuffer */
363	GLuint framebuffer;
364	glGenFramebuffers(1, &framebuffer);
365	glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
366	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
367		GL_RENDERBUFFER, depthbuffer);
368	glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER,
369		GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0, samples);
370
371	/* handle unsupported cases */
372	if (glCheckFramebufferStatus(GL_FRAMEBUFFER) !=
373			GL_FRAMEBUFFER_COMPLETE)
374	{
375		...
376	}
377
378	/* draw to the texture */
379	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
380	...
381
382	/* Discard the depth renderbuffer contents if possible */
383	if (extension_supported("GL_EXT_discard_framebuffer"))
384	{
385		GLenum discard_attachments[] = { GL_DEPTH_ATTACHMENT };
386		glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1,
387			discard_attachments);
388	}
389
390	/* Draw to the default framebuffer using the antialiased texture */
391	/* Color data is implicitly resolved before the texture gets used */
392	glBindFramebuffer(GL_FRAMEBUFFER, 0);
393	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
394		GL_STENCIL_BUFFER_BIT);
395	glBindTexture(GL_TEXTURE_2D, texture);
396	...
397
398Conformance Tests
399
400    No conformance test has been defined yet
401
402Issues
403
404    1. Which operations can cause a resolve?
405       The IMG_multisampled_render_to_texture includes this list:
406           - Drawing with the texture bound to an active texture unit
407           - ReadPixels or CopyTex[Sub]Image* while the texture is
408             attached to the framebuffer
409           - CopyTex[Sub]Image*, Tex[Sub]Image*,
410             CompressedTex[Sub]Image* with the specified level as
411             destination
412           - GenerateMipmap
413       An implementation may also want to resolve the multisample buffer on
414       operations such as:
415            - Flush and Finish when a multisampled texture or render-
416              buffer is attached to the current framebuffer.
417            - BindFramebuffer when the currently bound framebuffer has a
418              multisampled texture or renderbuffer attachment.
419
420    RESOLVED: Allow, but don't require, all of the above to cause a resolve.
421
422    2. Should there be a way for applications to query if the multisample
423       buffer has been resolved - and therefore is undefined?
424
425       This may be useful if the operations that cause the multisample
426       buffer to be resolved is allowed to vary between implementations.
427
428    RESOLVED: No, for two reasons: 1) This extension aims to be backwards
429    compatible with the IMG_multisampled_render_to_texture extension, which
430    did not include such a query, and 2) Given the resolution of issue 3 this
431    is not very useful as the application cannot control whether multisample
432    information is preserved or not.
433
434    3. Should there be a way for applications to preserve the multisample
435       buffer after a resolve?
436
437    This would be similar in spirit to the EGL_BUFFER_PRESERVED options in
438    EGL 1.4. Applications could - at a performance and memory cost - choose
439    to make the multisample buffer _not_ undefined after a resolve.
440
441    RESOLVED: No. The purpose of this extension is to support multisampled
442    rendering in a lightway manner. Preserving the multisample buffer goes
443    against this intent.
444
445    4. Should TEXTURE_SAMPLES_EXT rather be called FRAMEBUFFER_ATTACHMENT_-
446       TEXTURE_SAMPLES_EXT?
447
448    TEXTURE_SAMPLES is used in desktop GL to refer to the number of samples in
449    a multisampled texture. This extension does not introduce multisampled
450    textures, but rather allows multisampled rendering to non-multisampled
451    textures. For the purposes of this extension, the texture sample count
452    should be considered framebuffer attachment state rather than texture
453    state, thus FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT is a more
454    appropriate name.
455
456    RESOLVED: Use FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT.
457
458    5. Is CopyTex[Sub]Image2D allowed if the texture has implicit multisamples?
459       And is ReadPixels allowed if the texture or renderbuffer has implicit
460       multisamples?
461
462    RESOLVED: Yes.
463
464    This extension is written against OpenGL ES 2.0, which did not have multi-
465    sampled textures or renderbuffers. With this extension, an application can
466    use FramebufferTexture2DMultisampleEXT to associate multisample data with
467    an existing texture, or use RenderbufferStorageMultisampleEXT to allocate
468    a renderbuffer with associated multisample data. This does not add any
469    restrictions on the usage of such texture and renderbuffers beyond what
470    ES 2.0 defines, but any operations (such as CopyTexImage2D and ReadPixels)
471    may cause the multisample data to be resolved and lost. That is, the intent
472    of this extension is that implementations do not have to allocate multi-
473    sample data in system memory, but can store these data in internal high-
474    speed memory only, and implicitly downsample whenever those data need to
475    by visible is system memory.
476
477    6. What are the interactions with OpenGL ES 3.0 and later?
478
479    RESOLVED.
480
481    If this extension is supported in OpenGL ES 3.0 or later then
482    DRAW_FRAMEBUFFER and READ_FRAMEBUFFER are valid values for the <target>
483    parameter to FramebufferTexture2DMultisampleEXT. Since this parameter is
484    defined to correspond to - and have the same restrictions as - the <target>
485    parameter to FramebufferTexture2D, this also implies that FRAMEBUFFER is
486    equivalent to DRAW_FRAMEBUFFER for this command.
487
488    Note that this behavior was first described in revision 6 of this extension,
489    and was undefined in earlier revisions of this spec. Drivers written against
490    these earlier versions may generate errors if DRAW_FRAMEBUFFER and READ_-
491    FRAMEBUFFER are used for the <target> parameter to
492    FramebufferTexture2DMultisampleEXT.
493
494    7. What is the language about automatic resolves about?
495
496    RESOLVED.
497
498    The GL specification is written as if the multisample buffer is a separate
499    buffer from the color buffer. This is not quite how modern GPUs work, but
500    was true for some historic systems. This extension builds on the existing
501    specification wording and uses the existing terminology.
502
503    In the Multisampling section, the GL specification says that:
504
505    "The color sample values are resolved to a single, displayable color. For
506     window system-provided framebuffers, this occurs each time a pixel is
507     updated, so the antialiasing appears to be automatic at the application
508     level."
509
510    In practice, most GPUs will only resolve the color sample values once
511    (e.g. at the end of a frame), but from the application's point of view that
512    does not make any observable difference.
513
514    This extension inherits this behavor. The application does not (and cannot)
515    do anything to resolve the multisamples - this is always done automatically.
516
517    Further, this extension does not change any of the semantics around how
518    resources are synchronized. E.g. an attachment will always see the most
519    recent change made to the attached texture, whether that was done by
520    rendering into an attachment or by a texture update operation.
521
522    This implies that the multisample buffer and the color buffer are always
523    "in sync". The only behavior that is implementation-defined in this
524    extension is when the implicit multisample buffer is discarded. After the
525    operations that may (or may not) cause such a discard, an application can
526    observe either 1 or n distinct values in the multisample buffer depending
527    on whether the discard happened or not. As described in Issue 2, there's
528    no way for the application to query whether the discard happened.
529
530
531Revision History
532
533    Revision 8, 2018/04/11
534     - Clarified wording around implicit resolves, and added Issue 7.
535
536    Revision 7, 2016/06/28
537     - Clarified that it is an error to call FramebufferTexture2DMultisampleEXT
538       with a sample count higher than what is supported for the given internalformat.
539     - Added Framebuffer Attachment Completeness rule.
540
541    Revision 6, 2016/04/06
542     - Updating interactions with OpenGL ES 3.0 and added the related
543       Issue 6.
544
545    Revision 5, 2015/01/05
546     - Clarified that multisampled data is also implictly resolved for render-
547       buffers.
548     - Clarified interactions with multisampled textures in OpenGL ES 3.x.
549     - Added interaction with OpenGL ES 3.1.
550     - Added Issue 5.
551
552    Revision 4, 2012/07/04
553     - Fixing bug where enum names clashed with enums in the GL extension
554       EXT_framebuffer_multisample, but with different values defined.
555       This causes obvious problems. As a consequence, values have been
556       updated for the following enums:
557          * RENDERBUFFER_SAMPLES_EXT
558          * FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT
559          * MAX_SAMPLES_EXT
560       The values now match the values in EXT_framebuffer_multisample.
561
562    Revision 3, 2011/11/21
563      - Fixing a bug in Sample Code where GL_DEPTH_EXT was used instead of
564        GL_DEPTH_ATTACHMENT.
565
566    Revision 2, 2011/10/30
567      - Renaming to EXT extension. Resolving issues 1-4.
568
569    Revision 1, 2011/10/02
570      - First draft of XXX extension (based on IMG extension with the same name)
571