• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    IMG_framebuffer_downsample
4
5Name Strings
6
7    GL_IMG_framebuffer_downsample
8
9Contributors
10
11    Tobias Hector, Imagination Technologies (tobias.hector 'at' imgtec.com)
12
13Contact
14
15    Tobias Hector (tobias.hector 'at' imgtec.com)
16
17Status
18
19    Complete
20
21Version
22
23    Last Modified Date: August 20, 2015
24    Revision: 11
25
26Number
27
28    OpenGL ES Extension #255
29
30Dependencies
31
32    OpenGL ES 2.0 or OES_framebuffer_object are required.
33
34    This extension is written against the OpenGL ES 3.0.4 Specification
35    (August 27, 2014).
36
37    This extension has interactions with GL_EXT_multisampled_render_to_texture.
38
39    This extension has interactions with OpenGL ES 3.1.
40
41    This extension has interactions with GL_EXT_color_buffer_float.
42
43    This extension has interactions with GL_EXT_color_buffer_half_float.
44
45Overview
46
47    This extension introduces the ability to attach color buffers to a
48    framebuffer that are at a lower resolution than the framebuffer itself, with
49    the GPU automatically downsampling the color attachment to fit.
50
51    This can be useful for various post-process rendering techniques where it is
52    desirable to generate downsampled images in an efficient manner, or for a
53    lower resolution post-process technique.
54
55    This extension exposes at least a 2 x 2 downscale. Other downsampling modes
56    may be exposed on the system and this can be queried.
57
58IP Status
59
60    No known IP claims.
61
62New Procedures and Functions
63
64    void FramebufferTexture2DDownsampleIMG(
65            enum target, enum attachment,
66            enum textarget, uint texture,
67            int level, int xscale, int yscale);
68
69    void FramebufferTextureLayerDownsampleIMG(
70            enum target, enum attachment,
71            uint texture, int level,
72            int layer, int xscale, int yscale);
73
74New Tokens
75
76    Returned by CheckFramebufferStatus:
77
78        FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_AND_DOWNSAMPLE_IMG 0x913C
79
80    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv,
81    GetInteger64v, and GetInternalFormativ:
82
83        NUM_DOWNSAMPLE_SCALES_IMG                             0x913D
84
85    Accepted by the <target> parameter of GetIntegerv, GetInteger64v,
86    GetIntegeri_v, GetInteger64i_v and GetInternalFormativ:
87
88        DOWNSAMPLE_SCALES_IMG                                 0x913E
89
90    Accepted by the <pname> parameter of GetFramebufferAttachmentParameteriv:
91
92        FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG              0x913F
93
94Additions to Chapter 4 of the OpenGL ES 3.0 Specification:
95
96    Modify figure 4.1, "Per-Fragment Operations.", to add an additional box
97    "Downscaling" after "Additional Multisample Fragment Operations".
98
99    Add a new section 4.1.11, "Downscaling":
100
101        If no multisampling was performed, and downscaling is enabled, fragment
102        outputs may be optionally downscaled in a similar way to how multiple
103        samples are resolved. If the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_-
104        SCALE_IMG is not {1,1}, fragment values are written to an intermediate
105        buffer. After all other fragment operations have completed, they are
106        then combined to a produce a single color value, and that value is
107        written into the corresponding color buffer selected by DrawBuffers. An
108        implementation may defer the writing of color buffers until a later
109        time, but the state of the framebuffer must behave as if the color
110        buffers were updated as each fragment is processed. The method of
111        combination is not specified. If the framebuffer contains sRGB values,
112        then it is recommended that an average of samples is computed in a
113        linearized space, as for blending (see section 4.1.7). Otherwise, a
114        simple average computed independently for each color component is
115        recommended.
116
117    Add the following to Section 4.4.2 "Attaching Images to Framebuffer Objects"
118    after the paragraph describing FramebufferTexture2D:
119
120        The command
121
122            void FramebufferTexture2DDownsampleIMG(
123                    enum target, enum attachment,
124                    enum textarget, uint texture,
125                    int level, uint xscale, uint yscale);
126
127        allows a rendering into the image of a texture object that has a lower
128        resolution than the framebuffer.
129
130        target, textarget, texture, and level correspond to the same
131        parameters for FramebufferTexture2D and have the same restrictions.
132
133        attachment corresponds to the same parameter for FramebufferTexture2D,
134        but must be COLOR_ATTACHMENTn.
135
136        xscale and yscale are multiplied by texture's width and height,
137        respectively, to produce the effective size of the attachment when
138        rendering. For example, a texture width of 128 with an xscale of 2 would
139        produce a color attachment with the effective width of 256. xscale and
140        yscale must be one of the value pairs in DOWNSAMPLE_SCALES_IMG. If the
141        xscale and yscale value pair is not available on the implementation,
142        then the error INVALID_VALUE is generated.
143
144        The implementation allocates an implicit color buffer for the same
145        internalformat as the specified texture, and widths and heights from the
146        specified texture level, multiplied by xscale and yscale. This buffer is
147        used as the target for rendering instead of the specified texture level.
148        The buffer is associated with the attachment and gets deleted after the
149        attachment is broken.
150
151        When the texture level is used as a source or destination for any
152        operation, the attachment is flushed, or when the attachment is broken,
153        an implicit downsample of the color data from the color buffer to the
154        texture level may be performed. After such a downsample, the contents
155        of the color buffer become undefined.
156
157        The operations which may cause a resolve include:
158            * Drawing with the texture bound to an active texture unit
159            * ReadPixels or CopyTex[Sub]Image* while the texture is
160              attached to the framebuffer
161            * CopyTex[Sub]Image*, Tex[Sub]Image*,
162              CompressedTex[Sub]Image* with the specified level as
163              destination
164            * GenerateMipmap
165            * Flush or Finish while the texture is attached to the
166              framebuffer
167            * BindFramebuffer while the texture is attached to the currently
168              bound framebuffer.
169
170        Whether each of the above cause a resolve or not is implementation-
171        dependent.
172
173    Add the following to the sub-section "Attaching Texture Images to a
174    Framebuffer" after the paragraph describing FramebufferTextureLayer:
175
176        The command
177
178            void FramebufferTextureLayerDownsampleIMG(
179                    enum target, enum attachment,
180                    uint texture, int level,
181                    int layer, uint xscale, uint yscale);
182
183        allows a rendering into a single layer of a texture object that has a
184        lower resolution than the framebuffer. It operates like a combination of
185        FramebufferTexture2DDownsampleIMG and FramebufferTextureLayer; it allows
186        the developer to set scaling values and attaches a single layer of a
187        three-dimensional or two-dimensional array texture level.
188
189        target, attachment, level, xscale and yscale correspond to the same
190        parameters for FramebufferTexture2DDownsampleIMG and have the same
191        restrictions.
192
193        texture can only be a two-dimensional array texture, but otherwise has
194        the same restrictions as it does for FramebufferTextureLayer.
195
196        layer corresponds to the same parameter for FramebufferTextureLayer and
197        has the same restrictions.
198
199    In the sub-section "Effects of Attaching a Texture Image", change the bullet
200    list to the following:
201
202        * The value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is set to TEXTURE.
203        * The value of FRAMEBUFFER_ATTACHMENT_OBJECT_NAME is set to texture.
204        * The value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL is set to level.
205        * If FramebufferTexture2D is called and texture is a cube map texture,
206          then the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE is set
207          to textarget; otherwise it is set to the default (NONE).
208        * If FramebufferTextureLayer is called, then the value of FRAMEBUFFER_-
209          ATTACHMENT_TEXTURE_LAYER is set to layer; otherwise it is set to zero.
210        * If FramebufferTexture2DDownsampleIMG or
211          FramebufferTextureLayerDownsampleIMG is called, then the value of
212          FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG is set to {xscale, yscale};
213          otherwise it is set to {1, 1}.
214
215    In section 4.4.4 "Framebuffer Completeness", add the following bullet to the
216    end of the list in subsection "Framebuffer Attachment Completeness":
217
218
219        * If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is TEXTURE and the
220          value of FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG is supported by the
221          internal format of the attachment (see GetInternalFormativ in section
222          6.1.15).
223
224    In section 4.4.4 "Framebuffer Completeness", add the following bullet to the
225    end of the list in subsection "Whole Framebuffer Completeness":
226
227        * The value of FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG for all
228          attachments is {1,1}, or if not, the value of TEXTURE_SAMPLES_EXT or
229          RENDERBUFFER_SAMPLES for all attachments is zero.
230          FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_AND_DOWNSAMPLE_IMG
231
232Additions to Chapter 6 of the OpenGL ES 3.0 Specification:
233
234    Add the following bullet point to the list in Section 6.1.13 "Framebuffer
235    Object Queries" describing valid pname values when FRAMEBUFFER_ATTACHMENT_-
236    OBJECT_TYPE is TEXTURE:
237
238        * If pname is FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG, then params will
239          contain two integer values - the downsample scale pair for that
240          attachment.
241
242    Change the paragraph in Section 6.1.15 "Internal Format Queries" describing
243    valid target values to:
244
245        target indicates the usage of the internalformat, and must be one of
246    RENDERBUFFER, TEXTURE_2D, TEXTURE_CUBE_MAP or TEXTURE_2D_ARRAY.
247
248    Add the following paragraphs to Section 6.1.15 "Internal Format Queries" to
249    the paragraphs describing valid pname values:
250
251        If pname is NUM_DOWNSAMPLE_SCALES_IMG, the number of downscales that
252    would be returned by querying DOWNSAMPLE_SCALES_IMG is returned in params.
253        If pname is DOWNSAMPLE_SCALES_IMG, the available downscale pairs for the
254    format are written into params.
255        Formats that don't support downsampling will still return one valid
256    downsample scale pair - {1,1}. A value of one for NUM_DOWNSAMPLE_SCALES_IMG
257    will always mean no downscaling available, as {1,1} must be supported by
258    every format. Targets that don't support downscaling (e.g. RENDERBUFFER)
259    will return no downsample scale pairs.
260
261Interactions with OpenGL ES 2.0
262
263    In section 4.4.5 of the OpenGL ES 2.0 Specification "Framebuffer
264    Completeness", subsection "Framebuffer Attachment Completeness", replace:
265
266        * All attached images have the same width and height.
267          FRAMEBUFFER_INCOMPLETE_DIMENSIONS
268
269    with:
270
271        * All attached images have the same value of width * xscale and
272          height * yscale.
273          FRAMEBUFFER_INCOMPLETE_DIMENSIONS
274
275Interactions with OpenGL ES 3.1
276
277    If OpenGL ES 3.1 is supported, replace TEXTURE_SAMPLES_EXT with TEXTURE_-
278    SAMPLES, and add TEXTURE_2D_MULTISAMPLE to the list of valid targets for
279    GetInternalFormativ.
280
281Interactions with EXT_multisampled_render_to_texture
282
283    If EXT_multisampled_render_to_texture is not supported:
284        - ignore references to TEXTURE_SAMPLES_EXT
285        - the sample counts returned by GetInternalFormativ with a target of
286          TEXTURE* will be the sample values available to be used with
287          FramebufferTexture2DMultisampleEXT
288
289Dependencies on OpenGL ES 3.0
290
291    If OpenGL ES 3.0 or higher is not supported, ignore references to
292    glFramebufferTextureLayerDownsample and glGetIntegeri_v.
293
294Interactions with EXT_color_buffer_float and EXT_color_buffer_half_float
295
296    If either of these extensions are supported, it is not guaranteed that
297    downscale of these formats is supported, but it may be - users will have to
298    check with the GetInternalFormat query.
299
300    This equally applies to any other additional render formats provided by
301    extension.
302
303Errors
304
305    The error INVALID_VALUE is generated if FramebufferTextureLayerDownsampleIMG
306    or FramebufferTexture2DDownsampleIMG are are called with an <xscale> and
307    <yscale> value pair that isn't reported by DOWNSAMPLE_SCALES_IMG.
308
309    The error INVALID_ENUM is generated if FramebufferTextureLayerDownsampleIMG
310    or FramebufferTexture2DDownsampleIMG are called with an <attachment> that is
311    not COLOR_ATTACHMENTn.
312
313New State
314
315    Add to Table 6.14 "Framebuffer (state per attachment point)"
316
317                                                        Initial
318    Get Value         Type        Get Command           Value   Description     Sec.
319    ----------------- ----------- --------------------- ------- --------------- ----
320    FRAMEBUFFER_-     2 x Z+      GetFramebuffer-       {1,1}   Framebuffer     4.4.2
321    ATTACHMENT_-                  AttachmentParameteriv         texture scale
322    TEXTURE_SCALE_IMG
323
324New Implementation Dependent State
325
326    Add to Table 6.35 "Framebuffer Dependent Values"
327                                                     Minimum
328    Get Value         Type        Get Command        Value   Description     Sec.
329    ----------------- ----------- ------------------ ------- --------------- ----
330    NUM_DOWNSAMPLE_-  2 x Z+      GetIntegerv        2       Number of       4.4.2
331    SCALES_IMG                                               scale value
332                                                             pairs available
333
334    DOWNSAMPLE_-      1* x 2 x Z+ GetIntegeri_v      **      Scale value     4.4.2
335    SCALES_IMG                                               pairs available
336
337
338    ** At least {1,1} and {2,2} must be supported as a minimum to support this extension.
339
340Example
341
342    GLint xDownscale = 1;
343    GLint yDownscale = 1;
344
345    // Select a downscale amount if possible
346    if (extension_is_supported("GL_IMG_framebuffer_downsample")
347    {
348        // Query the number of available scales
349        GLint numScales;
350        glGetIntegerv(GL_NUM_DOWNSAMPLE_SCALES_IMG, &numScales);
351
352        // 2 scale modes are supported as minimum, so only need to check for
353        // better than 2x2 if more modes are exposed.
354        if (numScales > 2)
355        {
356            // Try to select most aggressive scaling.
357            GLint bestScale = 1;
358            GLint tempScale[2];
359            GLint i;
360            for (i = 0; i < numScales; ++i)
361            {
362                glGetIntegeri_v(GL_DOWNSAMPLE_SCALES_IMG, i, tempScale);
363
364                // If the scaling is more aggressive, update our x/y scale values.
365                if (tempScale[0] * tempScale[1] > bestScale)
366                {
367                    xDownscale = tempScale[0];
368                    yDownscale = tempScale[1];
369                }
370            }
371        }
372        else
373        {
374            xDownscale = 2;
375            yDownscale = 2;
376        }
377    }
378
379    // Create depth texture. Depth and stencil buffers must be full size
380    GLuint depthTexture;
381    glGenTextures(1, &depthTexture);
382    glBindTexture(GL_TEXTURE_2D, depthTexture);
383    glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT16, width, height);
384    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
385    glBindTexture(GL_TEXTURE_2D, 0);
386
387    // Create a full size RGBA texture with single mipmap level
388    GLuint texture;
389    glGenTextures(1, &texture);
390    glBindTexture(GL_TEXTURE_2D, texture);
391    glTexStorage2D(GL_TEXTURE_2D, 0, GL_RGBA4, width, height);
392    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
393    glBindTexture(GL_TEXTURE_2D, 0);
394
395    // Scale the width and height appropriately.
396    GLint scaledWidth = width / xDownscale;
397    GLint scaledHeight = height / yDownscale;
398
399    // Create a reduced size RGBA texture with single mipmap level
400    GLuint scaledTexture;
401    glGenTextures(1, &scaledTexture);
402    glBindTexture(GL_TEXTURE_2D, scaledTexture);
403    glTexStorage2D(GL_TEXTURE_2D, 0, GL_RGBA4, scaledWidth, scaledHeight);
404    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
405    glBindTexture(GL_TEXTURE_2D, 0);
406
407    // Create framebuffer object, attach textures
408    GLuint framebuffer;
409    glGenFramebuffers(1, &framebuffer);
410    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
411    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
412        GL_TEXTURE_2D, depthTexture);
413    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
414        GL_TEXTURE_2D, texture, 0);
415    glFramebufferTexture2DDownsampleIMG(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
416        GL_TEXTURE_2D, scaledTexture, 0, xDownscale, yDownscale);
417
418    // Handle unsupported cases
419    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
420    {
421        ...
422    }
423
424    // Draw to the texture
425    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
426    ...
427
428    // Discard the depth renderbuffer contents if possible/available
429    if (extension_supported("GL_EXT_discard_framebuffer"))
430    {
431        GLenum discard_attachments[] = { GL_DEPTH_ATTACHMENT };
432        glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discard_attachments);
433    }
434
435    /*
436        Draw to the default framebuffer using the textures with various post
437        processing effects.
438    */
439    glBindFramebuffer(GL_FRAMEBUFFER, 0);
440    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
441    glActiveTexture(GL_TEXTURE0);
442    glBindTexture(GL_TEXTURE_2D, texture);
443    glActiveTexture(GL_TEXTURE1);
444    glBindTexture(GL_TEXTURE_2D, scaledTexture);
445    ...
446
447Issues
448
449    1) Should renderbuffers be resolvable in this way too?
450
451       RESOLVED
452
453       No, renderbuffers are considered somewhat legacy and thus will
454       not be supported by this extension.
455
456    2) Should any scale values other than {1,1} be mandated as minimum?
457
458       RESOLVED
459
460       Yes, {2,2} will also be required. Implementations may support additional
461       values though, so a query is also added for other values.
462
463    3) What formats support downscaling?
464
465       RESOLVED
466
467       Formats that are guaranteed color-renderable by the core ES 3.1
468       specification, excluding integer and signed integer formats, support all
469       available downscale modes. Other formats only support {1,1} (no
470       downscaling).
471
472    4) What should happen if an application calls GetInternalFormativ with a
473       target of TEXTURE* (not TEXTURE_2D_MULTISAMPLE)?
474
475       RESOLVED
476
477       For standard OpenGL ES, NUM_SAMPLE_COUNTS should be zero. However, if
478       EXT_multisampled_render_to_texture is supported, valid configurations
479       for FramebufferTexture2DMultisampleEXT should be returned here.
480
481Revision History
482
483    Revision 1, 2014/08/27
484      - First draft
485
486    Revision 2, 2015/03/16
487      - Mandated {2,2} as a required downsample scale.
488      - Coupled x and y scale values into pairs
489
490    Revision 3, 2015/03/19
491      - Moved framebuffer completeness information to correct (whole framebuffer
492        completeness) section, and corrected wording.
493      - Added note about minimum support in the overview.
494
495    Revision 4, 2015/03/19
496      - Added a specific revision of the OpenGL ES 3.0 specification
497      - Added an error that only COLOR_ATTACHMENTn can be used as an attachment
498        point
499
500    Revision 5, 2015/06/02
501      - Added internalformat query capability, so that formats can opt into
502        downscaling support
503      - Added section on downscaling to per-fragment operations.
504      - Added issue about what formats support downscaling.
505      - Restricted layer downscaling to 2D array textures.
506
507    Revision 6, 2015/06/03
508      - Fixed typo in incomplete framebuffer condition
509      - Added a bullet point to describe the FRAMEBUFFER_ATTACHMENT_TEXTURE_-
510        SCALE_IMG parameter to GetFramebufferAttachmentiv
511      - Clarified targets to GetInternalFormativ
512
513    Revision 7, 2015/06/17
514      - Clarified interactions with EXT_color_buffer_float and
515        EXT_color_buffer_half_float
516
517    Revision 8, 2015/06/22
518      - Added NUM_DOWNSAMPLE_SCALES_IMG as a parameter to GetInternalFormativ
519      - Added framebuffer attachment incomplete message and removed error when
520        scale pair isn't supported by textures' internalformat, as
521        internalformat is not necessarily known at attachment time.
522
523    Revision 9, 2015/08/19
524      - Assigned enum values
525
526    Revision 10, 2015/08/20
527      - Allowed DOWNSAMPLE_SCALES_IMG to be used with GetIntegerv/GetInteger64v
528
529    Revision 11, 2015/12/18
530      - Fixed example - "tempScale" is an array so doesn't need to be dereferenced.
531