• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    EXT_pixel_buffer_object
4
5Name Strings
6
7    GL_EXT_pixel_buffer_object
8
9Status
10
11    Implemented by NVIDIA drivers (Release 55).
12
13Contributors
14
15    Ralf Biermann
16    Derek Cornish
17    Matt Craighead
18    Bill Licea-Kane
19    Brian Paul
20
21Contact
22
23    Ralf Biermann, NVIDIA Corporation (rbiermann 'at' nvidia.com)
24    Derek Cornish, NVIDIA Corporation (dcornish 'at' nvidia.com)
25
26IP Status
27
28    Unknown.
29
30Version
31
32    NVIDIA Date: March 29, 2004 (version 1.0)
33
34Number
35
36    302
37
38Status
39
40    NVIDIA Release 55 (early 2004) drivers support this extension.
41
42Dependencies
43
44    Written based on the wording of the OpenGL 1.5 specification.
45
46    GL_NV_pixel_data_range affects the definition of this extension.
47
48Overview
49
50    This extension expands on the interface provided by buffer objects.
51    It is intended to permit buffer objects to be used not only with
52    vertex array data, but also with pixel data.
53    Buffer objects were promoted from the ARB_vertex_buffer_object
54    extension in OpenGL 1.5.
55
56    Recall that buffer objects conceptually are nothing more than arrays
57    of bytes, just like any chunk of memory. Buffer objects allow GL
58    commands to source data from a buffer object by binding the buffer
59    object to a given target and then overloading a certain set of GL
60    commands' pointer arguments to refer to offsets inside the buffer,
61    rather than pointers to user memory.  An offset is encoded in a
62    pointer by adding the offset to a null pointer.
63
64    This extension does not add any new functionality to buffer
65    objects themselves.  It simply adds two new targets to which buffer
66    objects can be bound: PIXEL_PACK_BUFFER and PIXEL_UNPACK_BUFFER.
67    When a buffer object is bound to the PIXEL_PACK_BUFFER target,
68    commands such as ReadPixels write their data into a buffer object.
69    When a buffer object is bound to the PIXEL_UNPACK_BUFFER target,
70    commands such as DrawPixels read their data from a buffer object.
71
72    There are a wide variety of applications for such functionality.
73    Some of the most interesting ones are:
74
75    - "Render to vertex array."  The application can use a fragment
76      program to render some image into one of its buffers, then read
77      this image out into a buffer object via ReadPixels.  Then, it can
78      use this buffer object as a source of vertex data.
79
80    - Streaming textures.  If the application uses MapBuffer/UnmapBuffer
81      to write its data for TexSubImage into a buffer object, at least
82      one of the data copies usually required to download a texture can
83      be eliminated, significantly increasing texture download
84      performance.
85
86    - Asynchronous ReadPixels.  If an application needs to read back a
87      number of images and process them with the CPU, the existing GL
88      interface makes it nearly impossible to pipeline this operation.
89      The driver will typically send the hardware a readback command
90      when ReadPixels is called, and then wait for all of the data to
91      be available before returning control to the application.  Then,
92      the application can either process the data immediately or call
93      ReadPixels again; in neither case will the readback overlap with
94      the processing.  If the application issues several readbacks into
95      several buffer objects, however, and then maps each one to process
96      its data, then the readbacks can proceed in parallel with the data
97      processing.
98
99Issues
100
101    How does this extension relate to ARB_vertex_buffer_object?
102
103        It builds on the ARB_vertex_buffer_object framework by adding
104        two new targets that buffers can be bound to.
105
106    How does this extension relate to NV_pixel_data_range?
107
108        This extension relates to NV_pixel_data_range in the same way that
109        ARB_vertex_buffer_object relates to NV_vertex_array_range. To
110        paraphrase the ARB_vertex_buffer_object spec, here are the main
111        differences:
112
113        - Applications are no longer responsible for memory management
114          and synchronization.
115
116        - Applications may still access high-performance memory directly,
117          but this is optional, and such access is more restricted.
118
119        - Buffer changes (BindBuffer) are generally expected to
120          be very lightweight, rather than extremely heavyweight
121          (PixelDataRangeNV).
122
123        - A platform-specific allocator such as wgl/glXAllocateMemoryNV
124          is no longer required.
125
126    Can a given buffer be used for both vertex and pixel data?
127
128        RESOLVED: YES.  All buffers can be used with all buffer bindings,
129        in whatever combinations the application finds useful.  Consider
130        yourself warned, however, by the following issue.
131
132    May implementations make use of the target as a hint to select an
133    appropriate memory space for the buffer?
134
135        RESOLVED: YES, as long as such behavior is transparent to the
136        application. Some implementations may choose, for example,
137        that they would rather stream vertex data from write-combined
138        system memory, element (or index) data from video memory, and
139        pixel data from video memory.
140
141        In fact, one can imagine arbitrarily complicated heuristics for
142        selecting the memory space, based on factors such as the target,
143        the "usage" argument, and the application's observed behavior.
144
145        While it is entirely legal to create a buffer object by binding
146        it to ARRAY_BUFFER and loading it with data, then using it with
147        the PIXEL_UNPACK_BUFFER_EXT or PIXEL_PACK_BUFFER_EXT binding, such
148        behavior is liable to confuse the driver and may hurt performance.
149        If the driver implemented the hypothetical heuristic described
150        earlier, such a buffer might have already been located in
151        write-combined system memory, and so the driver would have to
152        choose between two bad options: relocate the buffer into video
153        memory, or accept lower performance caused by streaming pixel
154        data from slower system memory.
155
156    Should all pixel path commands be supported, or just a subset of
157    them?
158
159        RESOLVED: ALL.  While there is little reason to believe that,
160        say, ConvolutionFilter2D would benefit from this extension, there
161        is no reason _not_ to support it.  The full list of commands
162        affected by this extension is listed in the spec.
163
164    Should PixelMap and GetPixelMap be supported?
165
166        RESOLVED: YES.  They're not really pixel path operations, but,
167        again, there is no good reason to omit operations, and they _are_
168        operations that pass around big chunks of pixel-related data.
169        If we support PolygonStipple, surely we should support this.
170
171    How does the buffer binding state push/pop?
172
173        RESOLVED: As part of the pixel store client state.  This is
174        analogous to how the vertex buffer object bindings pushed/popped
175        as part of the vertex array client state.
176
177    Should NV_pixel_data_range (PDR) be used concurrently with pixel
178    buffer objects ?
179
180        RESOLVED: NO. While it would be possible to allocate a memory
181        range for PDR, using a pointer into this memory range with one
182        of the commands affected by EXT_pixel_buffer_object will not
183        work if a pixel buffer object other than zero is bound to the
184        buffer binding point affecting the command. Pixel buffer objects
185        always have higher precedence than PDR.
186
187    Do the null pointer rules for glTexImage1D, glTexImage2D
188    and glTexImage3D for allocating textures with undefined
189    content also apply when a non-zero buffer object is bound to
190    PIXEL_UNPACK_BUFFER_BINDING_EXT ?
191
192        RESOLVED: NO. The null pointer is interpreted as a non-zero
193        pointer to the data storage whose contents may be still
194        undefined. This data will be used to create the texture array.
195        If the null pointer rule is required, no non-zero buffer object
196        should be bound to PIXEL_UNPACK_BUFFER_BINDING_EXT.
197
198New Procedures and Functions
199
200    None.
201
202New Tokens
203
204    Accepted by the <target> parameters of BindBuffer, BufferData,
205    BufferSubData, MapBuffer, UnmapBuffer, GetBufferSubData,
206    GetBufferParameteriv, and GetBufferPointerv:
207
208        PIXEL_PACK_BUFFER_EXT                        0x88EB
209        PIXEL_UNPACK_BUFFER_EXT                      0x88EC
210
211    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
212    GetFloatv, and GetDoublev:
213
214        PIXEL_PACK_BUFFER_BINDING_EXT                0x88ED
215        PIXEL_UNPACK_BUFFER_BINDING_EXT              0x88EF
216
217
218Additions to Chapter 2 of the GL Specification (OpenGL Operation)
219
220    None
221
222Additions to Chapter 3 of the 1.2.1 Specification (Rasterization)
223
224    Additions to subsection 3.8.1 of the 1.2.1 Specification (Texture
225    Image Specification)
226
227    The extension EXT_pixel_buffer_object makes an exception to this
228    rule of passing a null pointer to glTexImage1D, glTexImage2D and
229    glTexImage3D. If PIXEL_UNPACK_BUFFER_BINDING_EXT is non-zero
230    and a null pointer is passed to these functions, the texture
231    array is created and the image contents are sourced from the
232    data store of the bound buffer object.
233
234Additions to Chapter 4 of the 1.2.1 Specification (Per-Fragment
235Operations and the Frame Buffer)
236
237    Added a subsection 4.3.5 (Pixel Buffer Object unpack operation)
238    in section 4.3 (Drawing, Reading and copying Pixels)
239
240    The extension EXT_pixel_buffer_object affects the operation of
241    several OpenGL commands described in section 3.6 (Pixel Rectangles),
242    section 3.7 (Bitmaps), and section 3.8 (Texturing).
243
244    In unextended OpenGL 1.3 with ARB_imaging support, the commands
245    glBitmap, glColorSubTable, glColorTable, glCompressedTexImage1D,
246    glCompressedTexImage2D, glCompressedTexImage3D,
247    glCompressedTexSubImage1D, glCompressedTexSubImage2D,
248    glCompressedTexSubImage3D, glConvolutionFilter1D,
249    glConvolutionFilter2D, glDrawPixels, glPixelMapfv, glPixelMapuiv,
250    glPixelMapusv, glPolygonStipple, glSeparableFilter2D, glTexImage1D,
251    glTexImage2D, glTexImage3D, glTexSubImage1D, glTexSubImage2D
252    and glTexSubImage3D operate as previously defined, except
253    that pixel data is sourced from a buffer object's data store if
254    PIXEL_UNPACK_BUFFER_BINDING_EXT is non-zero. When the data is sourced
255    from a buffer object, the pointer value passed in as an argument to
256    the command is used to compute an offset, in basic machine units,
257    into the data store of the buffer object. This offset is computed
258    by subtracting a null pointer from the pointer value, where both
259    pointers are treated as pointers to basic machine units.
260
261Additions to Chapter 5 of the 1.2.1 Specification (Special Functions)
262
263    None
264
265Additions to Chapter 6 of the 1.2.1 Specification (State and State
266Requests)
267
268    Additions to subsection 6.1.13 (Buffer Object Queries) in chapter 6
269
270    In unextended OpenGL 1.5 with ARB_imaging support, the commands
271    glGetColorTable, glGetCompressedTexImage, glGetConvolutionFilter,
272    glGetHistogram, glGetMinmax, glGetPixelMapfv, glGetPixelMapuiv,
273    glGetPixelMapusv, glGetPolygonStipple, glGetSeparableFilter,
274    glGetTexImage and glReadPixels operate as previously defined,
275    except that pixel data is stored in a buffer object's data store if
276    PIXEL_PACK_BUFFER_BINDING_EXT is non-zero. When a buffer object is
277    the target of the pixel data, the target pointer value passed in as
278    an argument to the command is used to compute an offset, in basic
279    machine units, into the data store of the buffer object. This offset
280    is computed by subtracting a null pointer from the pointer value,
281    where both pointers are treated as pointers to basic machine units.
282
283Errors
284
285    None
286
287New State
288
289(table 6.20, Pixels, p. 235)
290
291    Get Value                        Type  Get Command  Initial Value  Sec     Attribute
292    ---------                        ----  -----------  -------------  ---     ---------
293    PIXEL_PACK_BUFFER_BINDING_EXT    Z+    GetIntegerv  0              4.3.5   pixel-store
294    PIXEL_UNPACK_BUFFER_BINDING_EXT  Z+    GetIntegerv  0              6.1.13  pixel-store
295
296New Implementation Dependent State
297
298    (none)
299
300
301Usage Examples
302
303    Convenient macro definition for specifying buffer offsets:
304
305        #define BUFFER_OFFSET(i) ((char *)NULL + (i))
306
307    Example 1: Render to vertex array
308
309        // create a buffer object for a number of vertices consisting of
310        // 4 float values per vertex
311        GenBuffers(1, vertexBuffer);
312        BindBuffer(PIXEL_PACK_BUFFER_EXT, vertexBuffer);
313        BufferData(PIXEL_PACK_BUFFER_EXT, numberVertices*4, NULL, DYNAMIC_DRAW);
314
315        // render vertex data into framebuffer using a fragment program
316        BindProgramARB(FRAGMENT_PROGRAM_ARB, fragmentProgram);
317        DrawBuffer(GL_BACK);
318        renderVertexData();
319        BindProgramARB(FRAGMENT_PROGRAM_ARB, 0);
320
321        // read the vertex data back from framebuffer
322        ReadBuffer(GL_BACK);
323        ReadPixels(0, 0, numberVertices*4, height/2,
324            GL_BGRA, GL_FLOAT, BUFFER_OFFSET(0));
325
326        // change the binding point of the buffer object to
327        // the vertex array binding point
328        BindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
329
330        EnableClientState(VERTEX_ARRAY);
331        VertexPointer(4, FLOAT, 0, BUFFER_OFFSET(0));
332        DrawArrays(TRIANGLE_STRIP, 0, numberVertices);
333
334    Example 2: Streaming textures
335
336    streaming textures using NV_pixel_data_range
337
338        void *pdrMemory, *texData;
339
340        pdrMemory = AllocateMemoryNV(texsize, 0.0, 1.0, 1.0);
341
342        PixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV, texsize, pdrMemory);
343
344        EnableClientState(GL_WRITE_PIXEL_DATA_RANGE_NV);
345
346        // setup texture environment
347        ...
348
349        texData = getNextImage();
350
351        while (texData) {
352
353            memcpy(pdrMemory, texData, texsize);
354
355            FlushPixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV);
356
357            TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
358                texWidth, texHeight, GL_BGRA, GL_UNSIGNED_BYTE, pdrMemory);
359
360            // draw textured geometry
361            Begin(GL_QUADS);
362            ...
363            End();
364
365            texData = getNextImage();
366        }
367
368        DisableClientState(GL_WRITE_PIXEL_DATA_RANGE_NV);
369
370        FreeMemoryNV(pdrMemory);
371
372    streaming textures using EXT_pixel_buffer_object:
373
374        void *pboMemory, *texData;
375
376        // create and bind texture image buffer object
377        GenBuffers(1, &texBuffer);
378        BindBuffer(PIXEL_UNPACK_BUFFER_EXT, texBuffer);
379        BufferData(PIXEL_UNPACK_BUFFER_EXT, texSize, NULL, STREAM_DRAW);
380
381        texData = getNextImage();
382
383        while (texData) {
384
385            // map the texture image buffer
386            pboMemory = MapBuffer(PIXEL_UNPACK_BUFFER_EXT, WRITE_ONLY);
387
388            // modify (sub-)buffer data
389            memcpy(pboMemory, texData, texsize);
390
391            // unmap the texture image buffer
392            if (!UnmapBuffer(PIXEL_UNPACK_BUFFER_EXT)) {
393                // Handle error case
394            }
395
396            // update (sub-)teximage from texture image buffer
397            TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight,
398                          GL_BGRA, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
399
400            // draw textured geometry
401            Begin(GL_QUADS);
402            ...
403            End();
404
405            texData = getNextImage();
406        }
407
408        BindBuffer(PIXEL_UNPACK_BUFFER_EXT, 0);
409
410    Example 3: Asynchronous ReadPixels
411
412    traditional ReadPixels
413
414        unsigned int readBuffer[imagewidth*imageheight*4];
415
416        // render to framebuffer
417        DrawBuffer(GL_BACK);
418        renderScene()
419
420        // read image from framebuffer
421        ReadBuffer(GL_BACK);
422        ReadPixels();
423
424        // process image when ReadPixels returns after reading the whole buffer
425        processImage(readBuffer);
426
427    asynchronous ReadPixels
428
429        GenBuffers(2, imageBuffers);
430
431        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[0]);
432        BufferData(PIXEL_PACK_BUFFER_EXT, imageSize / 2, NULL, STATIC_READ);
433
434        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[1]);
435        BufferData(PIXEL_PACK_BUFFER_EXT, imageSize / 2, NULL, STATIC_READ);
436
437        // render to framebuffer
438        DrawBuffer(GL_BACK);
439        renderScene();
440
441        // Bind two different buffer objects and start the ReadPixels
442        // asynchronously. Each call will return directly after starting the
443        // DMA transfer.
444        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[0]);
445        ReadPixels(0, 0, width, height/2,
446            GL_BGRA, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
447
448        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[1]);
449        ReadPixels(0, height/2, width, height/2, GL_BGRA, GL_UNSIGNED_BYTE,
450                   BUFFER_OFFSET(0));
451
452        // process partial images
453        pboMemory1 = MapBuffer(PIXEL_PACK_BUFFER_EXT, READ_ONLY);
454        processImage(pboMemory1);
455        pboMemory2 = MapBuffer(PIXEL_PACK_BUFFER_EXT, READ_ONLY);
456        processImage(pboMemory2);
457
458        // unmap the image buffers
459        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[0]);
460        if (!UnmapBuffer(PIXEL_PACK_BUFFER_EXT)) {
461            // Handle error case
462        }
463        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[1]);
464        if (!UnmapBuffer(PIXEL_PACK_BUFFER_EXT)) {
465            // Handle error case
466        }
467