back  Return to list

GL_EXT_pixel_buffer_object
homeprevnext Name
  
    EXT_pixel_buffer_object  
  
homeprevnext Name Strings
  
    GL_EXT_pixel_buffer_object  
  
homeprevnext Status
  
    Implemented by NVIDIA drivers (Release 55).  
  
homeprevnext Contributors
  
    Ralf Biermann  
    Derek Cornish  
    Matt Craighead  
    Bill Licea-Kane  
    Brian Paul  
  
homeprevnext Contact
  
    Ralf Biermann, NVIDIA Corporation (rbiermann 'at' nvidia.com)  
    Derek Cornish, NVIDIA Corporation (dcornish 'at' nvidia.com)  
  
homeprevnext IP Status
  
    Unknown.  
  
homeprevnext Version
  
    NVIDIA Date: March 29, 2004 (version 1.0)  
  
homeprevnext Number
  
    ???  
  
homeprevnext Status
  
    NVIDIA Release 55 (early 2004) drivers support this extension.  
  
homeprevnext Dependencies
  
    Written based on the wording of the OpenGL 1.5 specification.  
  
    GL_NV_pixel_data_range affects the definition of this extension.  
  
homeprevnext Overview
  
    This extension expands on the interface provided by buffer objects.  
    It is intended to permit buffer objects to be used not only with   
    vertex array data, but also with pixel data.  
    Buffer objects were promoted from the ARB_vertex_buffer_object  
    extension in OpenGL 1.5.  
  
    Recall that buffer objects conceptually are nothing more than arrays  
    of bytes, just like any chunk of memory. Buffer objects allow GL  
    commands to source data from a buffer object by binding the buffer  
    object to a given target and then overloading a certain set of GL  
    commands' pointer arguments to refer to offsets inside the buffer,  
    rather than pointers to user memory.  An offset is encoded in a  
    pointer by adding the offset to a null pointer.  
  
    This extension does not add any new functionality to buffer  
    objects themselves.  It simply adds two new targets to which buffer  
    objects can be bound: PIXEL_PACK_BUFFER and PIXEL_UNPACK_BUFFER.  
    When a buffer object is bound to the PIXEL_PACK_BUFFER target,  
    commands such as ReadPixels write their data into a buffer object.  
    When a buffer object is bound to the PIXEL_UNPACK_BUFFER target,  
    commands such as DrawPixels read their data from a buffer object.  
  
    There are a wide variety of applications for such functionality.  
    Some of the most interesting ones are:  
  
    - "Render to vertex array."  The application can use a fragment  
      program to render some image into one of its buffers, then read  
      this image out into a buffer object via ReadPixels.  Then, it can  
      use this buffer object as a source of vertex data.  
  
    - Streaming textures.  If the application uses MapBuffer/UnmapBuffer  
      to write its data for TexSubImage into a buffer object, at least  
      one of the data copies usually required to download a texture can  
      be eliminated, significantly increasing texture download  
      performance.  
  
    - Asynchronous ReadPixels.  If an application needs to read back a  
      number of images and process them with the CPU, the existing GL  
      interface makes it nearly impossible to pipeline this operation.  
      The driver will typically send the hardware a readback command  
      when ReadPixels is called, and then wait for all of the data to  
      be available before returning control to the application.  Then,  
      the application can either process the data immediately or call  
      ReadPixels again; in neither case will the readback overlap with  
      the processing.  If the application issues several readbacks into  
      several buffer objects, however, and then maps each one to process  
      its data, then the readbacks can proceed in parallel with the data  
      processing.  
  
homeprevnext Issues
  
    How does this extension relate to ARB_vertex_buffer_object?  
  
        It builds on the ARB_vertex_buffer_object framework by adding  
        two new targets that buffers can be bound to.  
  
    How does this extension relate to NV_pixel_data_range?  
  
        This extension relates to NV_pixel_data_range in the same way that  
        ARB_vertex_buffer_object relates to NV_vertex_array_range. To  
        paraphrase the ARB_vertex_buffer_object spec, here are the main  
        differences:  
  
        - Applications are no longer responsible for memory management  
          and synchronization.  
  
        - Applications may still access high-performance memory directly,  
          but this is optional, and such access is more restricted.  
  
        - Buffer changes (BindBuffer) are generally expected to  
          be very lightweight, rather than extremely heavyweight  
          (PixelDataRangeNV).  
  
        - A platform-specific allocator such as wgl/glXAllocateMemoryNV  
          is no longer required.  
  
    Can a given buffer be used for both vertex and pixel data?  
  
        RESOLVED: YES.  All buffers can be used with all buffer bindings,  
        in whatever combinations the application finds useful.  Consider  
        yourself warned, however, by the following issue.  
  
    May implementations make use of the target as a hint to select an  
    appropriate memory space for the buffer?  
  
        RESOLVED: YES, as long as such behavior is transparent to the  
        application. Some implementations may choose, for example,  
        that they would rather stream vertex data from write-combined  
        system memory, element (or index) data from video memory, and  
        pixel data from video memory.  
  
        In fact, one can imagine arbitrarily complicated heuristics for  
        selecting the memory space, based on factors such as the target,  
        the "usage" argument, and the application's observed behavior.  
  
        While it is entirely legal to create a buffer object by binding  
        it to ARRAY_BUFFER and loading it with data, then using it with  
        the PIXEL_UNPACK_BUFFER_EXT or PIXEL_PACK_BUFFER_EXT binding, such  
        behavior is liable to confuse the driver and may hurt performance.  
        If the driver implemented the hypothetical heuristic described  
        earlier, such a buffer might have already been located in  
        write-combined system memory, and so the driver would have to  
        choose between two bad options: relocate the buffer into video  
        memory, or accept lower performance caused by streaming pixel  
        data from slower system memory.  
  
    Should all pixel path commands be supported, or just a subset of  
    them?  
  
        RESOLVED: ALL.  While there is little reason to believe that,  
        say, ConvolutionFilter2D would benefit from this extension, there  
        is no reason _not_ to support it.  The full list of commands  
        affected by this extension is listed in the spec.  
  
    Should PixelMap and GetPixelMap be supported?  
  
        RESOLVED: YES.  They're not really pixel path operations, but,  
        again, there is no good reason to omit operations, and they _are_  
        operations that pass around big chunks of pixel-related data.  
        If we support PolygonStipple, surely we should support this.  
  
    How does the buffer binding state push/pop?  
  
        RESOLVED: As part of the pixel store client state.  This is  
        analogous to how the vertex buffer object bindings pushed/popped  
        as part of the vertex array client state.  
  
    Should NV_pixel_data_range (PDR) be used concurrently with pixel  
    buffer objects ?  
  
        RESOLVED: NO. While it would be possible to allocate a memory  
        range for PDR, using a pointer into this memory range with one  
        of the commands affected by EXT_pixel_buffer_object will not  
        work if a pixel buffer object other than zero is bound to the  
        buffer binding point affecting the command. Pixel buffer objects  
        always have higher precedence than PDR.  
  
    Do the null pointer rules for glTexImage1D, glTexImage2D  
    and glTexImage3D for allocating textures with undefined  
    content also apply when a non-zero buffer object is bound to  
    PIXEL_UNPACK_BUFFER_BINDING_EXT ?  
          
        RESOLVED: NO. The null pointer is interpreted as a non-zero  
        pointer to the data storage whose contents may be still  
        undefined. This data will be used to create the texture array.  
        If the null pointer rule is required, no non-zero buffer object  
        should be bound to PIXEL_UNPACK_BUFFER_BINDING_EXT.  
  
homeprevnext New Procedures and Functions
  
    None.  
  
homeprevnext New Tokens
  
    Accepted by the <target> parameters of BindBuffer, BufferData,   
    BufferSubData, MapBuffer, UnmapBuffer, GetBufferSubData,   
    GetBufferParameteriv, and GetBufferPointerv:  
  
        PIXEL_PACK_BUFFER_EXT                        0x88EB  
        PIXEL_UNPACK_BUFFER_EXT                      0x88EC  
  
    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,  
    GetFloatv, and GetDoublev:  
  
        PIXEL_PACK_BUFFER_BINDING_EXT                0x88ED  
        PIXEL_UNPACK_BUFFER_BINDING_EXT              0x88EF  
  
  
homeprevnext Additions to Chapter 2 of the GL Specification (OpenGL Operation)
  
    None  
  
homeprevnext Additions to Chapter 3 of the 1.2.1 Specification (Rasterization)
  
    Additions to subsection 3.8.1 of the 1.2.1 Specification (Texture  
    Image Specification)  
  
    The extension EXT_pixel_buffer_object makes an exception to this  
    rule of passing a null pointer to glTexImage1D, glTexImage2D and  
    glTexImage3D. If PIXEL_UNPACK_BUFFER_BINDING_EXT is non-zero  
    and a null pointer is passed to these functions, the texture  
    array is created and the image contents are sourced from the  
    data store of the bound buffer object.  
  
homeprevnext Additions to Chapter 4 of the 1.2.1 Specification (Per-Fragment Operations and the Frame Buffer)
  
    Added a subsection 4.3.5 (Pixel Buffer Object unpack operation)  
    in section 4.3 (Drawing, Reading and copying Pixels)  
  
    The extension EXT_pixel_buffer_object affects the operation of  
    several OpenGL commands described in section 3.6 (Pixel Rectangles),  
    section 3.7 (Bitmaps), and section 3.8 (Texturing).  
  
    In unextended OpenGL 1.3 with ARB_imaging support, the commands  
    glBitmap, glColorSubTable, glColorTable, glCompressedTexImage1D,  
    glCompressedTexImage2D, glCompressedTexImage3D,  
    glCompressedTexSubImage1D, glCompressedTexSubImage2D,  
    glCompressedTexSubImage3D, glConvolutionFilter1D,  
    glConvolutionFilter2D, glDrawPixels, glPixelMapfv, glPixelMapuiv,  
    glPixelMapusv, glPolygonStipple, glSeparableFilter2D, glTexImage1D,  
    glTexImage2D, glTexImage3D, glTexSubImage1D, glTexSubImage2D  
    and glTexSubImage3D operate as previously defined, except  
    that pixel data is sourced from a buffer object's data store if  
    PIXEL_UNPACK_BUFFER_BINDING_EXT is non-zero. When the data is sourced  
    from a buffer object, the pointer value passed in as an argument to  
    the command is used to compute an offset, in basic machine units,  
    into the data store of the buffer object. This offset is computed  
    by subtracting a null pointer from the pointer value, where both  
    pointers are treated as pointers to basic machine units.  
  
homeprevnext Additions to Chapter 5 of the 1.2.1 Specification (Special Functions)
  
    None  
  
homeprevnext Additions to Chapter 6 of the 1.2.1 Specification (State and State Requests)
  
    Additions to subsection 6.1.13 (Buffer Object Queries) in chapter 6  
      
    In unextended OpenGL 1.5 with ARB_imaging support, the commands  
    glGetColorTable, glGetCompressedTexImage, glGetConvolutionFilter,  
    glGetHistogram, glGetMinmax, glGetPixelMapfv, glGetPixelMapuiv,  
    glGetPixelMapusv, glGetPolygonStipple, glGetSeparableFilter,  
    glGetTexImage and glReadPixels operate as previously defined,  
    except that pixel data is stored in a buffer object's data store if  
    PIXEL_PACK_BUFFER_BINDING_EXT is non-zero. When a buffer object is  
    the target of the pixel data, the target pointer value passed in as  
    an argument to the command is used to compute an offset, in basic  
    machine units, into the data store of the buffer object. This offset  
    is computed by subtracting a null pointer from the pointer value,  
    where both pointers are treated as pointers to basic machine units.  
  
homeprevnext Errors
  
    None  
  
homeprevnext New State
  
(table 6.20, Pixels, p. 235)  
  
    Get Value                        Type  Get Command  Initial Value  Sec     Attribute  
    ---------                        ----  -----------  -------------  ---     ---------  
    PIXEL_PACK_BUFFER_BINDING_EXT    Z+    GetIntegerv  0              4.3.5   pixel-store  
    PIXEL_UNPACK_BUFFER_BINDING_EXT  Z+    GetIntegerv  0              6.1.13  pixel-store  
  
homeprevnext New Implementation Dependent State
  
    (none)  
  
  
homeprevnext Usage Examples
  
    Convenient macro definition for specifying buffer offsets:  
  
        #define BUFFER_OFFSET(i) ((char *)NULL + (i))  
  
    Example 1: Render to vertex array  
  
        // create a buffer object for a number of vertices consisting of   
        // 4 float values per vertex  
        GenBuffers(1, vertexBuffer);  
        BindBuffer(PIXEL_PACK_BUFFER_EXT, vertexBuffer);  
        BufferData(PIXEL_PACK_BUFFER_EXT, numberVertices*4, NULL, DYNAMIC_DRAW);  
  
        // render vertex data into framebuffer using a fragment program  
        BindProgramARB(FRAGMENT_PROGRAM_ARB, fragmentProgram);  
        DrawBuffer(GL_BACK);  
        renderVertexData();  
        BindProgramARB(FRAGMENT_PROGRAM_ARB, 0);  
  
        // read the vertex data back from framebuffer  
        ReadBuffer(GL_BACK);  
        ReadPixels(0, 0, numberVertices*4, height/2,  
            GL_BGRA, GL_FLOAT, BUFFER_OFFSET(0));  
  
        // change the binding point of the buffer object to  
        // the vertex array binding point  
        BindBuffer(GL_ARRAY_BUFFER, vertexBuffer);  
  
        EnableClientState(VERTEX_ARRAY);  
        VertexPointer(4, FLOAT, 0, BUFFER_OFFSET(0));  
        DrawArrays(TRIANGLE_STRIP, 0, numberVertices);  
  
    Example 2: Streaming textures  
  
    streaming textures using NV_pixel_data_range   
  
        void *pdrMemory, *texData;  
  
        pdrMemory = AllocateMemoryNV(texsize, 0.0, 1.0, 1.0);  
  
        PixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV, texsize, pdrMemory);  
  
        EnableClientState(GL_WRITE_PIXEL_DATA_RANGE_NV);  
  
        // setup texture environment  
        ...       
  
        texData = getNextImage();  
  
        while (texData) {  
  
            memcpy(pdrMemory, texData, texsize);  
  
            FlushPixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV);  
  
            TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,  
                texWidth, texHeight, GL_BGRA, GL_UNSIGNED_BYTE, pdrMemory);  
  
            // draw textured geometry  
            Begin(GL_QUADS);  
            ...  
            End();  
  
            texData = getNextImage();  
        }  
  
        DisableClientState(GL_WRITE_PIXEL_DATA_RANGE_NV);  
  
        FreeMemoryNV(pdrMemory);  
      
    streaming textures using EXT_pixel_buffer_object:  
  
        void *pboMemory, *texData;  
  
        // create and bind texture image buffer object  
        GenBuffers(1, &texBuffer);  
        BindBuffer(PIXEL_UNPACK_BUFFER_EXT, texBuffer);  
        BufferData(PIXEL_UNPACK_BUFFER_EXT, texSize, NULL, STREAM_DRAW);  
  
        texData = getNextImage();  
  
        while (texData) {  
  
            // map the texture image buffer  
            pboMemory = MapBuffer(PIXEL_UNPACK_BUFFER_EXT, WRITE_ONLY);  
              
            // modify (sub-)buffer data  
            memcpy(pboMemory, texData, texsize);  
  
            // unmap the texture image buffer  
            if (!UnmapBuffer(PIXEL_UNPACK_BUFFER_EXT)) {  
                // Handle error case  
            }  
  
            // update (sub-)teximage from texture image buffer  
            TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight,   
                          GL_BGRA, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));  
  
            // draw textured geometry  
            Begin(GL_QUADS);  
            ...  
            End();  
  
            texData = getNextImage();  
        }  
  
        BindBuffer(PIXEL_UNPACK_BUFFER_EXT, 0);  
  
    Example 3: Asynchronous ReadPixels  
  
    traditional ReadPixels  
  
        unsigned int readBuffer[imagewidth*imageheight*4];  
  
        // render to framebuffer  
        DrawBuffer(GL_BACK);  
        renderScene()  
          
        // read image from framebuffer  
        ReadBuffer(GL_BACK);   
        ReadPixels();  
  
        // process image when ReadPixels returns after reading the whole buffer  
        processImage(readBuffer);  
  
    asynchronous ReadPixels  
  
        GenBuffers(2, imageBuffers);  
  
        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[0]);  
        BufferData(PIXEL_PACK_BUFFER_EXT, imageSize / 2, NULL, STATIC_READ);  
  
        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[1]);  
        BufferData(PIXEL_PACK_BUFFER_EXT, imageSize / 2, NULL, STATIC_READ);  
  
        // render to framebuffer  
        DrawBuffer(GL_BACK);  
        renderScene();  
  
        // Bind two different buffer objects and start the ReadPixels   
        // asynchronously. Each call will return directly after starting the   
        // DMA transfer.  
        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[0]);  
        ReadPixels(0, 0, width, height/2,  
            GL_BGRA, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));  
  
        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[1]);  
        ReadPixels(0, height/2, width, height/2, GL_BGRA, GL_UNSIGNED_BYTE,   
                   BUFFER_OFFSET(0));  
          
        // process partial images   
        pboMemory1 = MapBuffer(PIXEL_PACK_BUFFER_EXT, READ_ONLY);  
        processImage(pboMemory1);  
        pboMemory2 = MapBuffer(PIXEL_PACK_BUFFER_EXT, READ_ONLY);  
        processImage(pboMemory2);  
  
        // unmap the image buffers  
        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[0]);  
        if (!UnmapBuffer(PIXEL_PACK_BUFFER_EXT)) {  
            // Handle error case  
        }  
        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[1]);  
        if (!UnmapBuffer(PIXEL_PACK_BUFFER_EXT)) {  
            // Handle error case  
        }  
        }  
Valid XHTML 1.1! Valid CSS! Last update: November 14, 2006.
Cette page doit être lue avec un navigateur récent respectant le standard XHTML 1.1.